A tool to read animebox backup files and export the data in alternate formats.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

70 lines
1.8 KiB

use std::error::Error;
use std::ffi::OsString;
use std::fs::File;
use std::io::BufReader;
use std::path::Path;
use std::process::exit;
use serde::ser::Error as SerdeError;
use serde::{Deserialize, Serialize};
use serde_json::{from_reader, to_writer_pretty};
#[derive(Serialize, Deserialize, Debug)]
#[serde(deny_unknown_fields)]
pub struct State {
pub downloaded: Vec<String>,
}
pub struct StateManager {
state_path: OsString,
pub state: State,
}
fn read_state<P: AsRef<Path>>(path: P) -> Result<State, Box<dyn Error>> {
if path.as_ref().exists() {
let file = File::open(path)?;
let reader = BufReader::new(file);
let result: State = from_reader(reader)?;
Ok(result)
} else {
Ok(State { downloaded: vec![] })
}
}
fn save_state<P: AsRef<Path>>(path: P, state: &State) -> serde_json::Result<()> {
match File::create(path) {
Err(e) => Err(serde_json::Error::custom(e)),
Ok(file) => to_writer_pretty(file, state),
}
}
impl StateManager {
pub fn new(state_path: &Path) -> StateManager {
let mut state = StateManager {
state_path: OsString::from(state_path.as_os_str()),
state: State { downloaded: vec![] },
};
state.load();
state
}
fn load(&mut self) {
match read_state(&self.state_path) {
Err(e) => {
println!("Failed to read state file {:#?}: {}", &self.state_path, e);
exit(1);
}
Ok(state) => self.state = state,
}
}
pub fn save(&mut self, state: State) {
match save_state(&self.state_path, &state) {
Err(e) => {
println!("Unexpected error saving state: {}", e);
}
Ok(_) => (),
}
self.state = state;
}
}