kodik-rs 0.1.0

A Rust library for getting direct links to files from Kodik.
Documentation
use std::{
    fs::{self, File, OpenOptions},
    path::PathBuf,
    sync::LazyLock,
};

use kodik_parser::KODIK_STATE;
use serde::{Deserialize, Serialize};

pub static CACHE_PATH: LazyLock<Option<PathBuf>> =
    LazyLock::new(|| dirs::cache_dir().map(|cache_dir| cache_dir.join("kodik").join("cache.json")));

#[derive(Debug, Serialize, Deserialize, Default)]
pub struct Cache {
    pub shift: u8,
    pub endpoint: String,
}

impl Cache {
    pub fn load() -> Self {
        let Some(cache_path) = CACHE_PATH.as_ref() else {
            return Self::default();
        };

        if !cache_path.exists() {
            if let Some(parent) = cache_path.parent() {
                let _ = fs::create_dir_all(parent);
            }
            let _ = File::create(cache_path);
        }

        fs::read_to_string(cache_path).map_or_else(
            |_| Self::default(),
            |content| serde_json::from_str(&content).unwrap_or_default(),
        )
    }

    pub fn save(&self) -> Option<()> {
        let cache_path = CACHE_PATH.as_ref()?;
        let file = OpenOptions::new()
            .write(true)
            .truncate(true)
            .open(cache_path)
            .ok()?;
        serde_json::to_writer_pretty(file, self).ok()
    }

    pub fn update(&mut self) {
        self.shift = KODIK_STATE.shift();
        self.endpoint.clone_from(&KODIK_STATE.endpoint());
    }

    pub fn is_changed(&self) -> bool {
        self.shift != KODIK_STATE.shift()
            || self.endpoint.as_str() != KODIK_STATE.endpoint().as_str()
    }

    pub fn apply(&self) {
        KODIK_STATE.set_shift(self.shift);
        KODIK_STATE.set_endpoint(self.endpoint.clone());
    }
}