Move the logic to serialise and deserialise EtcTrees into the type's impl.

This commit is contained in:
r-vdp 2023-03-23 11:52:41 +01:00
parent 47f32ccea7
commit f7edf3a52f
No known key found for this signature in database
2 changed files with 38 additions and 42 deletions

View file

@ -80,7 +80,7 @@ pub fn activate(store_path: &StorePath, ephemeral: bool) -> Result<()> {
DirBuilder::new().recursive(true).create(&etc_dir)?; DirBuilder::new().recursive(true).create(&etc_dir)?;
let old_state = read_created_files()?; let old_state = EtcTree::from_file(&get_state_file()?)?;
let initial_state = EtcTree::root_node(); let initial_state = EtcTree::root_node();
let (state, status) = create_etc_static_link( let (state, status) = create_etc_static_link(
@ -91,20 +91,24 @@ pub fn activate(store_path: &StorePath, ephemeral: bool) -> Result<()> {
); );
status?; status?;
let new_state = create_etc_links(config.entries.values(), &etc_dir, state, &old_state) // Create the rest of the links and serialise the resulting state
.update_state(old_state, &try_delete_path); create_etc_links(config.entries.values(), &etc_dir, state, &old_state)
.update_state(old_state, &try_delete_path)
serialise_state(new_state)?; .unwrap_or_default()
.write_to_file(&get_state_file()?)?;
log::info!("Done"); log::info!("Done");
Ok(()) Ok(())
} }
pub fn deactivate() -> Result<()> { pub fn deactivate() -> Result<()> {
let state = read_created_files()?; let state = EtcTree::from_file(&get_state_file()?)?;
log::debug!("{:?}", state); log::debug!("{:?}", state);
serialise_state(state.deactivate(&try_delete_path))?; state
.deactivate(&try_delete_path)
.unwrap_or_default()
.write_to_file(&get_state_file()?)?;
log::info!("Done"); log::info!("Done");
Ok(()) Ok(())
@ -291,42 +295,10 @@ fn copy_file(source: &Path, target: &Path, mode: &str, old_state: &EtcTree) -> R
} }
} }
fn serialise_state<E>(created_files: Option<E>) -> Result<()> fn get_state_file() -> Result<PathBuf> {
where
E: AsRef<EtcTree>,
{
let state_file = Path::new(SYSTEM_MANAGER_STATE_DIR).join(ETC_STATE_FILE_NAME); let state_file = Path::new(SYSTEM_MANAGER_STATE_DIR).join(ETC_STATE_FILE_NAME);
DirBuilder::new() DirBuilder::new()
.recursive(true) .recursive(true)
.create(SYSTEM_MANAGER_STATE_DIR)?; .create(SYSTEM_MANAGER_STATE_DIR)?;
Ok(state_file)
log::info!("Writing state info into file: {}", state_file.display());
let writer = io::BufWriter::new(fs::File::create(state_file)?);
if let Some(e) = created_files {
serde_json::to_writer(writer, e.as_ref())?;
} else {
serde_json::to_writer(writer, &EtcTree::default())?;
}
Ok(())
}
fn read_created_files() -> Result<EtcTree> {
let state_file = Path::new(SYSTEM_MANAGER_STATE_DIR).join(ETC_STATE_FILE_NAME);
DirBuilder::new()
.recursive(true)
.create(SYSTEM_MANAGER_STATE_DIR)?;
if Path::new(&state_file).is_file() {
log::info!("Reading state info from {}", state_file.display());
let reader = io::BufReader::new(fs::File::open(state_file)?);
match serde_json::from_reader(reader) {
Ok(created_files) => return Ok(created_files),
Err(e) => {
log::error!("Error reading the state file, ignoring.");
log::error!("{:?}", e);
}
}
}
Ok(EtcTree::default())
} }

View file

@ -1,9 +1,10 @@
use anyhow::Result;
use im::HashMap; use im::HashMap;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use std::cmp::Eq; use std::cmp::Eq;
use std::iter::Peekable; use std::iter::Peekable;
use std::path;
use std::path::{Path, PathBuf}; use std::path::{Path, PathBuf};
use std::{fs, io, path};
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
@ -225,6 +226,29 @@ impl EtcTree {
Some(merged) Some(merged)
} }
pub fn write_to_file(&self, state_file: &Path) -> Result<()> {
log::info!("Writing state info into file: {}", state_file.display());
let writer = io::BufWriter::new(fs::File::create(state_file)?);
serde_json::to_writer(writer, self)?;
Ok(())
}
pub fn from_file(state_file: &Path) -> Result<Self> {
if state_file.is_file() {
log::info!("Reading state info from {}", state_file.display());
let reader = io::BufReader::new(fs::File::open(state_file)?);
match serde_json::from_reader(reader) {
Ok(created_files) => return Ok(created_files),
Err(e) => {
log::error!("Error reading the state file, ignoring.");
log::error!("{:?}", e);
}
}
}
Ok(Self::default())
}
} }
#[cfg(test)] #[cfg(test)]