From a8b568f8f2418be52db1ccd3d2732dd8ff6a24a3 Mon Sep 17 00:00:00 2001 From: Drew Short Date: Mon, 25 May 2020 19:25:09 -0500 Subject: [PATCH] Split config from state --- src/config.rs | 22 +---------------- src/main.rs | 30 +++++++++++++++-------- src/state.rs | 66 +++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 87 insertions(+), 31 deletions(-) create mode 100644 src/state.rs diff --git a/src/config.rs b/src/config.rs index ad43e90..a2f0af7 100644 --- a/src/config.rs +++ b/src/config.rs @@ -5,15 +5,13 @@ 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}; +use serde_json::from_reader; #[derive(Serialize, Deserialize, Debug)] #[serde(deny_unknown_fields)] pub struct Config { pub save_directory: Option, - pub downloaded: Vec, } pub struct ConfigManager { @@ -28,20 +26,12 @@ fn read_config>(path: P) -> Result> { Ok(result) } -fn save_config>(path: P, config: &Config) -> serde_json::Result<()> { - match File::create(path) { - Err(e) => Err(serde_json::Error::custom(e)), - Ok(file) => to_writer_pretty(file, config), - } -} - impl ConfigManager { pub fn new(config_path: &Path) -> ConfigManager { let mut config = ConfigManager { config_path: OsString::from(config_path.as_os_str()), config: Config { save_directory: None, - downloaded: vec![], }, }; config.load(); @@ -57,14 +47,4 @@ impl ConfigManager { Ok(config) => self.config = config, } } - - pub fn save(&mut self, config: Config) { - match save_config(&self.config_path, &config) { - Err(e) => { - println!("Unexpected error saving config: {}", e); - } - Ok(_) => (), - } - self.config = config; - } } diff --git a/src/main.rs b/src/main.rs index bc90b80..dc147d1 100644 --- a/src/main.rs +++ b/src/main.rs @@ -6,14 +6,16 @@ use std::path::Path; use std::process::exit; use clap::{App, Arg}; +use crossterm::{cursor, QueueableCommand}; use curl::easy::{Easy, WriteError}; use serde_json::from_reader; use url::Url; -use crate::config::{Config, ConfigManager}; -use crossterm::{cursor, QueueableCommand}; use lazy_static::lazy_static; +use crate::config::ConfigManager; +use crate::state::{State, StateManager}; + const VERSION: Option<&'static str> = option_env!("CARGO_PKG_VERSION"); lazy_static! { @@ -21,6 +23,7 @@ lazy_static! { } mod config; mod model; +mod state; fn read_animeboxes_backup>( path: P, @@ -69,9 +72,13 @@ fn print_progress(data: &[u8]) -> Result<(), Box> { Ok(()) } -fn download_command(backup: model::anime_boxes::Backup, mut config: config::ConfigManager) { +fn download_command( + backup: model::anime_boxes::Backup, + config_manager: config::ConfigManager, + mut state_manager: state::StateManager, +) { let temp_directory = env::current_dir().unwrap().join( - config + config_manager .config .save_directory .as_ref() @@ -88,7 +95,7 @@ fn download_command(backup: model::anime_boxes::Backup, mut config: config::Conf .collect(); let mut favorites_to_download: Vec = Vec::new(); for favorite in favorites { - if !config.config.downloaded.contains(&favorite) { + if !state_manager.state.downloaded.contains(&favorite) { favorites_to_download.push(favorite); } } @@ -155,7 +162,7 @@ fn download_command(backup: model::anime_boxes::Backup, mut config: config::Conf } let favorites_downloaded_count = favorites_downloaded.len(); let mut all_downloaded: Vec = Vec::new(); - for downloaded in &config.config.downloaded { + for downloaded in &state_manager.state.downloaded { all_downloaded.push(String::from(downloaded)); } for downloaded in favorites_downloaded { @@ -163,11 +170,10 @@ fn download_command(backup: model::anime_boxes::Backup, mut config: config::Conf all_downloaded.push(downloaded); } let all_downloaded_count = all_downloaded.len(); - let new_config = Config { - save_directory: Some(String::from(config.config.save_directory.as_ref().unwrap())), + let new_state = State { downloaded: all_downloaded, }; - config.save(new_config); + state_manager.save(new_state); println!( "Downloaded {:#?}/{:#?} images", favorites_downloaded_count, all_downloaded_count @@ -227,12 +233,16 @@ fn main() { let config = matches.value_of("config").unwrap_or("config.json"); let config_path = env::current_dir().unwrap().join(config); let config_manager = ConfigManager::new(config_path.as_path()); + + let state_path = env::current_dir().unwrap().join("state.json"); + let state_manager = StateManager::new(state_path.as_path()); + let path = matches.value_of("INPUT").unwrap(); let result = read_animeboxes_backup(path).unwrap(); let command = matches.value_of("COMMAND").unwrap(); match command { - "download" => download_command(result, config_manager), + "download" => download_command(result, config_manager, state_manager), "favorites" => favorites_command(result), "print" => println!("{:#?}", result), "searches" => searches_command(result), diff --git a/src/state.rs b/src/state.rs new file mode 100644 index 0000000..5e1623d --- /dev/null +++ b/src/state.rs @@ -0,0 +1,66 @@ +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> { + let file = File::open(path)?; + let reader = BufReader::new(file); + let result: State = from_reader(reader)?; + Ok(result) +} + +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; + } +}