diff --git a/src/cache/cache.rs b/src/cache/cache.rs index c6ff4e3..f4e2876 100644 --- a/src/cache/cache.rs +++ b/src/cache/cache.rs @@ -1,26 +1,19 @@ use std::fs; use std::io::{BufReader, BufWriter}; -use std::path::Path; - -use anyhow::Context; -use serde::{Deserialize, Serialize}; +use std::path::{Path, PathBuf}; +use super::CacheLine; use crate::cli::View; use crate::os::Os; -use super::CacheLine; - -const FILE_NAME: &'static str = "cache.json"; - -#[derive(Serialize, Deserialize, Debug)] +#[derive(Debug)] pub struct Cache { - day: Option, - hist_90: Option, - hist_day: Option, + cache_line: Option, + config_path: PathBuf, } impl Cache { - pub fn load() -> Option { + pub fn load(view: View) -> Option { let config_opt = Os::get_current()?.get_config_path(); let mut config_path = match config_opt { Ok(k) => k, @@ -33,17 +26,19 @@ impl Cache { eprintln!("Failed to create config dir: {:?}", e); return None; } - config_path.push(FILE_NAME); + config_path.push(format!("{}.json", view.get_name())); if !config_path.try_exists().unwrap_or_default() { return Some(Self { - day: None, - hist_90: None, - hist_day: None, + cache_line: None, + config_path, }); } match Self::read_config(&config_path) { - Ok(k) => Some(k), + Ok(cache_line) => Some(Self { + cache_line: Some(cache_line), + config_path, + }), Err(e) => { eprintln!("Config path is invalid, or cannot be created: {:?}", e); None @@ -51,44 +46,28 @@ impl Cache { } } - pub fn get_cache_line(&self, resolution: View) -> Option<&CacheLine> { - match resolution { - View::TODAY => self.day.as_ref(), - View::HistDays90 => self.hist_90.as_ref(), - View::HistDaysAll => self.hist_day.as_ref(), - } + pub fn get_cache_line(&self) -> Option<&CacheLine> { + self.cache_line.as_ref() } - pub fn set_cache_line(&mut self, resolution: View, cache_line: CacheLine) { - let cache_line_opt = Some(cache_line); - match resolution { - View::TODAY => self.day = cache_line_opt, - View::HistDays90 => self.hist_90 = cache_line_opt, - View::HistDaysAll => self.hist_day = cache_line_opt, - } + pub fn set_cache_line(&mut self, cache_line: CacheLine) { + self.cache_line = Some(cache_line); } pub fn save(&self) -> anyhow::Result<()> { - let mut config_path = Os::get_current() - .context("Failed to get config home")? - .get_config_path()?; - fs::create_dir_all(&config_path)?; - - config_path.push(FILE_NAME); - let file = fs::File::options() .write(true) .create(true) .truncate(true) - .open(&config_path)?; + .open(&self.config_path)?; let writer = BufWriter::new(file); - serde_json::to_writer(writer, self)?; + serde_json::to_writer(writer, &self.cache_line)?; Ok(()) } - fn read_config(path: &Path) -> anyhow::Result { + fn read_config(path: &Path) -> anyhow::Result { let file = fs::File::open(path)?; let reader = BufReader::new(file); Ok(serde_json::from_reader(reader)?) diff --git a/src/cli.rs b/src/cli.rs index f531f9d..9c73d30 100644 --- a/src/cli.rs +++ b/src/cli.rs @@ -46,8 +46,8 @@ pub struct Cli { pub max_decimals: u8, /// Amount of data - #[arg(value_enum, default_value_t = View::TODAY, long="resolution", short='r')] - pub resolution: View, + #[arg(value_enum, default_value_t = View::TODAY, long="view", short='v')] + pub view: View, } #[derive(Debug, Clone, Copy, ValueEnum)] @@ -74,6 +74,14 @@ impl View { View::HistDaysAll => ecb_url::hist::DAYS_ALL, } } + + pub fn get_name(&self) -> &'static str { + match self { + View::TODAY => "today", + View::HistDays90 => "last-90-days", + View::HistDaysAll => "all-days", + } + } } impl SortBy { diff --git a/src/main.rs b/src/main.rs index 38be7f6..353e666 100644 --- a/src/main.rs +++ b/src/main.rs @@ -25,25 +25,26 @@ async fn main() -> ExitCode { let mut header_description = HeaderDescription::new(); let use_cache = !cli.no_cache; - let mut cache = if use_cache { Cache::load() } else { None }; + let mut cache = if use_cache { + Cache::load(cli.view) + } else { + None + }; let cache_ok = cache.as_ref().map_or_else( || false, - |c| { - c.get_cache_line(cli.resolution) - .map_or_else(|| false, |cl| cl.is_valid()) - }, + |c| c.get_cache_line().map_or_else(|| false, |cl| cl.is_valid()), ); let mut parsed = if cache_ok { // These are safe unwraps cache .as_ref() .unwrap() - .get_cache_line(cli.resolution) + .get_cache_line() .unwrap() .exchange_rate_results .clone() } else { - let parsed = match get_and_parse(cli.resolution.to_ecb_url()).await { + let parsed = match get_and_parse(cli.view.to_ecb_url()).await { Ok(k) => k, Err(e) => { eprintln!("Failed to get/parse data from ECB: {}", e); @@ -56,7 +57,7 @@ async fn main() -> ExitCode { || true, |cache_local| { cache_local - .get_cache_line(cli.resolution) + .get_cache_line() .map_or_else(|| true, |cache_line| cache_line == &parsed) }, ); @@ -64,7 +65,7 @@ async fn main() -> ExitCode { if not_equal_cache { if let Some(cache_safe) = cache.as_mut() { let cache_line = CacheLine::new(parsed.clone()); - cache_safe.set_cache_line(cli.resolution, cache_line); + cache_safe.set_cache_line(cache_line); if let Err(e) = cache_safe.save() { eprintln!("Failed to save to cache with: {:?}", e); }