1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
|
use std::{
fs::{create_dir_all, exists, read, write, File},
path::{Path, PathBuf},
};
use anyhow::{Context, Result};
use serde::{Deserialize, Serialize};
const SCHIST_CACHE_DIR: &'static str = "schist";
const SCHIST_CACHE_FILENAME: &'static str = "schist_cache.toml";
#[derive(Default, Deserialize, Serialize)]
pub struct Cache {
pub last_open_file: Option<String>,
}
pub struct CacheKeys {
pub last_open_file: &'static str,
}
pub const CACHE_KEYS: CacheKeys = CacheKeys {
last_open_file: "last_open_file",
};
pub fn get_cache() -> Result<Cache> {
const CONTEXT: &'static str = "Failed to get cache";
let cache_filepath = get_and_touch_cache_filepath().context(CONTEXT)?;
let cache_toml = read(&cache_filepath).context(CONTEXT)?;
let cache_table: toml::Table = toml::from_slice(&cache_toml).context(CONTEXT)?;
Ok(Cache {
last_open_file: cache_table
.get(&CACHE_KEYS.last_open_file.to_string())
.map(|o| o.as_str().map(str::to_string))
.flatten(),
})
}
pub fn put_to_cache<T>(key: &str, value: T) -> Result<()>
where
toml::Value: From<T>,
{
const CONTEXT: &'static str = "Failed to save cache";
let cache_filepath = get_and_touch_cache_filepath().context(CONTEXT)?;
let curr_cache_toml = read(&cache_filepath).context(CONTEXT)?;
let mut cache: toml::Table = toml::from_slice(&curr_cache_toml).context(CONTEXT)?;
cache.insert(key.to_string(), value.into());
let new_cache_toml = toml::to_string(&cache).context(CONTEXT)?;
write(cache_filepath, new_cache_toml).context(CONTEXT)?;
Ok(())
}
pub fn remove_from_cache(key: &str) -> Result<()> {
const CONTEXT: &'static str = "Failed to remove key from cache";
let cache_filepath = get_and_touch_cache_filepath().context(CONTEXT)?;
let curr_cache_toml = read(&cache_filepath).context(CONTEXT)?;
let mut cache: toml::Table = toml::from_slice(&curr_cache_toml).context(CONTEXT)?;
cache.remove(key);
let new_cache_toml = toml::to_string(&cache).context(CONTEXT)?;
write(cache_filepath, new_cache_toml).context(CONTEXT)?;
Ok(())
}
fn get_and_touch_cache_filepath() -> Result<PathBuf, anyhow::Error> {
let cache_dir = get_and_make_schist_cache_dir()?;
let cache_filepath = cache_dir.join(Path::new(SCHIST_CACHE_FILENAME));
let does_cache_file_exist = exists(cache_filepath.clone())
.context("Failed to determine the existence of Schist's cache file")?;
if !does_cache_file_exist {
File::create(cache_filepath.clone()).context("Failed to create a new cache file")?;
}
Ok(cache_filepath)
}
fn get_and_make_schist_cache_dir() -> anyhow::Result<PathBuf> {
let cache_dir = dirs::cache_dir().context("Failed to get app cache directory")?;
let schist_cache_dir = cache_dir.join(Path::new(SCHIST_CACHE_DIR));
create_dir_all(&schist_cache_dir).context(format!(
"Failed to create app cache directory at {}",
schist_cache_dir.display()
))?;
println!("Found app cache directory at {:?}", schist_cache_dir);
Ok(schist_cache_dir)
}
|