Browse Source

Split config from state

master
Drew Short 4 years ago
parent
commit
a8b568f8f2
  1. 22
      src/config.rs
  2. 30
      src/main.rs
  3. 66
      src/state.rs

22
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<String>,
pub downloaded: Vec<String>,
}
pub struct ConfigManager {
@ -28,20 +26,12 @@ fn read_config<P: AsRef<Path>>(path: P) -> Result<Config, Box<dyn Error>> {
Ok(result)
}
fn save_config<P: AsRef<Path>>(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;
}
}

30
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<P: AsRef<Path>>(
path: P,
@ -69,9 +72,13 @@ fn print_progress(data: &[u8]) -> Result<(), Box<dyn Error>> {
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<String> = 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<String> = 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),

66
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<String>,
}
pub struct StateManager {
state_path: OsString,
pub state: State,
}
fn read_state<P: AsRef<Path>>(path: P) -> Result<State, Box<dyn Error>> {
let file = File::open(path)?;
let reader = BufReader::new(file);
let result: State = from_reader(reader)?;
Ok(result)
}
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;
}
}
Loading…
Cancel
Save