ecb_rates/caching/
cache.rs

1use std::fs;
2use std::io::{BufReader, BufWriter};
3use std::path::{Path, PathBuf};
4
5use super::CacheLine;
6use crate::View;
7use crate::os::Os;
8
9#[derive(Debug)]
10pub struct Cache {
11    cache_line: Option<CacheLine>,
12    config_path: PathBuf,
13}
14
15impl Cache {
16    pub fn load(view: &View) -> Option<Self> {
17        let config_opt = Os::get_current()?.get_config_path();
18        let mut config_path = match config_opt {
19            Ok(k) => k,
20            Err(e) => {
21                eprintln!("Failed to locate config dir: {:?}", e);
22                return None;
23            }
24        };
25        if let Err(e) = fs::create_dir_all(&config_path) {
26            eprintln!("Failed to create config dir: {:?}", e);
27            return None;
28        }
29        config_path.push(format!("{}.json", view.get_name()));
30        if !config_path.try_exists().unwrap_or_default() {
31            return Some(Self {
32                cache_line: None,
33                config_path,
34            });
35        }
36
37        match Self::read_config(&config_path) {
38            Ok(cache_line) => Some(Self {
39                cache_line: Some(cache_line),
40                config_path,
41            }),
42            Err(e) => {
43                eprintln!("Config path is invalid, or cannot be created: {:?}", e);
44                None
45            }
46        }
47    }
48
49    pub fn get_cache_line(&self) -> Option<&CacheLine> {
50        self.cache_line.as_ref()
51    }
52
53    pub fn set_cache_line(&mut self, cache_line: CacheLine) {
54        self.cache_line = Some(cache_line);
55    }
56
57    pub fn save(&self) -> anyhow::Result<()> {
58        let file = fs::File::options()
59            .write(true)
60            .create(true)
61            .truncate(true)
62            .open(&self.config_path)?;
63
64        let writer = BufWriter::new(file);
65        serde_json::to_writer(writer, &self.cache_line)?;
66
67        Ok(())
68    }
69
70    fn read_config(path: &Path) -> anyhow::Result<CacheLine> {
71        let file = fs::File::open(path)?;
72        let reader = BufReader::new(file);
73        Ok(serde_json::from_reader(reader)?)
74    }
75}