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, } pub struct StateManager { state_path: OsString, pub state: State, } fn read_state>(path: P) -> Result> { 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>(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; } }