rizzoo 0.6.9

a cross platform color generation tool implementing Material 3 Expressive
use sha2::{Digest, Sha256};
use std::path::Path;

use crate::color::types::ColorScheme;
use crate::error::LRatio;
use crate::paths::Paths;

pub fn cache_key(image_path: &Path, harmony: &str, is_light: bool, file_size: u64) -> String {
    let mut hasher = Sha256::new();
    hasher.update(harmony.as_bytes());
    hasher.update([if is_light { 1u8 } else { 0u8 }]);
    hasher.update(file_size.to_le_bytes());
    if let Ok(mut file) = std::fs::File::open(image_path) {
        use std::io::Read;
        let mut buffer = Vec::new();
        if file.read_to_end(&mut buffer).is_ok() {
            hasher.update(&buffer);
        }
    }
    let hash = hasher.finalize();
    hash.iter()
        .map(|b| format!("{:02x}", b))
        .collect::<String>()
}

pub fn load_scheme(paths: &Paths, key: &str) -> Result<Option<ColorScheme>, LRatio> {
    let path = paths.cache_colorscheme(key);
    if !path.exists() {
        return Ok(None);
    }
    match read_cache(&path) {
        Ok(dict) => Ok(Some(dict)),
        Err(_e) => {
            log::warn!("{}", LRatio::CacheCorrupted(path.clone()));
            let _ = std::fs::remove_file(&path);
            Ok(None)
        }
    }
}

pub fn save_scheme(paths: &Paths, key: &str, dict: &ColorScheme) -> Result<(), LRatio> {
    let path = paths.cache_colorscheme(key);
    let json = serde_json::to_string_pretty(dict)
        .map_err(|e| LRatio::CacheWrite(path.clone(), e.to_string()))?;
    std::fs::write(&path, json).map_err(|e| LRatio::CacheWrite(path.clone(), e.to_string()))?;
    Ok(())
}

fn read_cache(path: &Path) -> Result<ColorScheme, LRatio> {
    let contents = std::fs::read_to_string(path)
        .map_err(|e| LRatio::CacheRead(path.to_path_buf(), e.to_string()))?;
    serde_json::from_str(&contents).map_err(|_| LRatio::CacheCorrupted(path.to_path_buf()))
}

pub fn file_size(path: &Path) -> u64 {
    std::fs::metadata(path).map(|m| m.len()).unwrap_or(0)
}