use std::{
collections::HashMap,
hash::{DefaultHasher, Hash, Hasher},
path::{Path, PathBuf},
};
use serde::{Deserialize, Serialize};
use crate::{Error, extract::ExtractionConfig};
#[derive(Debug, Clone, Serialize, Deserialize, Default)]
pub struct Cache {
pub entries: HashMap<String, (u8, u8, u8)>,
}
impl Cache {
pub fn load_default() -> Self {
Self::load(Self::file())
}
pub fn load<P>(file: P) -> Self
where
P: AsRef<Path>,
{
match std::fs::read(file) {
Ok(bytes) => postcard::from_bytes(&bytes).unwrap_or_default(),
Err(_) => Self::default(),
}
}
pub fn save_default(&self) -> Result<(), Error> {
self.save(Self::file())
}
pub fn save<P>(&self, file: P) -> Result<(), Error>
where
P: AsRef<Path>,
{
let file = file.as_ref();
if let Some(parent) = file.parent() {
std::fs::create_dir_all(parent)?;
}
let encoded = postcard::to_allocvec(self)?;
std::fs::write(file, encoded)?;
Ok(())
}
pub fn key<P>(config: &ExtractionConfig, image: P) -> Result<String, Error>
where
P: AsRef<Path>,
{
let mut hasher = DefaultHasher::new();
let image = std::fs::canonicalize(image)?;
image.hash(&mut hasher);
if let Ok(Ok(modifier)) =
std::fs::metadata(image).map(|v| v.modified())
{
modifier.hash(&mut hasher);
}
config.hash(&mut hasher);
Ok(format!("{:x}", hasher.finish()))
}
pub fn dir() -> PathBuf {
dirs::cache_dir()
.unwrap_or_else(|| ".".into())
.join("gecol")
}
pub fn file() -> PathBuf {
Self::dir().join("colors.bin")
}
}