Fix cache bug

Fix bug where a potentially incorrect resolution would be assumed.
This commit is contained in:
2025-01-08 15:30:14 +01:00
parent 81ec482918
commit 96aabc8019
4 changed files with 84 additions and 27 deletions

96
src/cache/cache.rs vendored Normal file
View File

@ -0,0 +1,96 @@
use std::fs;
use std::io::{BufReader, BufWriter};
use std::path::Path;
use anyhow::Context;
use serde::{Deserialize, Serialize};
use crate::cli::Resolution;
use crate::os::Os;
use super::CacheLine;
const FILE_NAME: &'static str = "cache.json";
#[derive(Serialize, Deserialize, Debug)]
pub struct Cache {
day: Option<CacheLine>,
hist_90: Option<CacheLine>,
hist_day: Option<CacheLine>,
}
impl Cache {
pub fn load() -> Option<Self> {
let config_opt = Os::get_current()?.get_config_path();
let mut config_path = match config_opt {
Ok(k) => k,
Err(e) => {
eprintln!("Failed to locate config dir: {:?}", e);
return None;
}
};
if let Err(e) = fs::create_dir_all(&config_path) {
eprintln!("Failed to create config dir: {:?}", e);
return None;
}
config_path.push(FILE_NAME);
if !config_path.try_exists().unwrap_or_default() {
return Some(Self {
day: None,
hist_90: None,
hist_day: None,
});
}
match Self::read_config(&config_path) {
Ok(k) => Some(k),
Err(e) => {
eprintln!("Config path is invalid, or cannot be created: {:?}", e);
None
}
}
}
pub fn get_cache_line(&self, resolution: Resolution) -> Option<&CacheLine> {
match resolution {
Resolution::TODAY => self.day.as_ref(),
Resolution::HistDays90 => self.hist_90.as_ref(),
Resolution::HistDay => self.hist_day.as_ref(),
}
}
pub fn set_cache_line(&mut self, resolution: Resolution, cache_line: CacheLine) {
let cache_line_opt = Some(cache_line);
match resolution {
Resolution::TODAY => self.day = cache_line_opt,
Resolution::HistDays90 => self.hist_90 = cache_line_opt,
Resolution::HistDay => self.hist_day = cache_line_opt,
}
}
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)?;
let writer = BufWriter::new(file);
serde_json::to_writer(writer, self)?;
Ok(())
}
fn read_config(path: &Path) -> anyhow::Result<Self> {
let file = fs::File::open(path)?;
let reader = BufReader::new(file);
Ok(serde_json::from_reader(reader)?)
}
}

30
src/cache/cache_line.rs vendored Normal file
View File

@ -0,0 +1,30 @@
use chrono::serde::ts_seconds;
use chrono::{DateTime, Local, Utc};
use serde::{Deserialize, Serialize};
use crate::models::ExchangeRateResult;
#[derive(Serialize, Deserialize, Debug)]
pub struct CacheLine {
#[serde(with = "ts_seconds")]
date: DateTime<Utc>,
#[serde(rename = "camelCase")]
pub exchange_rate_results: Vec<ExchangeRateResult>,
}
impl CacheLine {
pub fn validate(&self) -> bool {
let today = Local::now().naive_local().date();
let saved = self.date.naive_local().date();
saved == today
}
pub fn new(exchange_rate_results: Vec<ExchangeRateResult>) -> Self {
let date = Local::now().to_utc();
Self {
exchange_rate_results,
date,
}
}
}

5
src/cache/mod.rs vendored Normal file
View File

@ -0,0 +1,5 @@
mod cache;
mod cache_line;
pub use cache::Cache;
pub use cache_line::CacheLine;