takoyaki_core 1.2.0

Core package to build plugins for takoyaki
Documentation
// Import dependencies
use crate::{Paths, TakoyakiError};
use serde::{Deserialize, Serialize};
use serde_json::Value;
use std::{
    fs::{create_dir_all, read_to_string, File},
    io::Write,
    path::PathBuf,
};

/// Cache struct is used to retrive and write to caches
pub struct Cache {
    /// The path of the cache
    cache_path: PathBuf,
}

// Add functions
impl Cache {
    /// Creates a new instance of the cache which can be used to write or retrieve caches
    ///
    /// Arguments:
    /// * name - The name of the plugin
    ///
    /// # Examples
    ///
    /// ```
    /// use takoyaki_core::Cache;
    /// let cache = Cache::new("my_plugin");
    /// ```
    pub fn new(name: &str) -> Self {
        // Return a self instance
        Self {
            cache_path: Paths::get_cache_path(name),
        }
    }

    /// Checks if the cache is corrupted or not
    ///
    /// Corruption is checked on the basis of file existance and validity
    ///
    /// # Examples
    ///
    /// ```
    /// use takoyaki_core::Cache;
    /// let cache = Cache::new("my_plugin");
    /// cache.is_corrupted();
    /// ```
    pub fn is_corrupted(&self) -> Result<bool, TakoyakiError> {
        // Check if the file exists
        if !self.cache_path.exists() {
            return Ok(true);
        }

        // Get the raw version
        let raw = read_to_string(&self.cache_path)?;

        // Try to parse it with serde_json
        serde_json::from_str::<Value>(&raw)?;

        // Yay! It is not corrupted
        Ok(false)
    }

    /// Reads the cache and returns it as a `T` type
    ///
    /// # Examples
    ///
    /// ```
    /// use takoyaki_core::Cache;
    /// use serde_json::Value;
    ///
    /// let cache = Cache::new("my_plugin");
    /// let parsed = cache.get::<Value>();
    /// ```
    pub fn get<T>(&self) -> Result<T, TakoyakiError>
    where
        T: for<'de> Deserialize<'de>,
    {
        // Check the validity of the file
        self.is_corrupted()?;

        // Read the cache as a raw string
        let raw = read_to_string(&self.cache_path)?;

        // Parse it
        let parsed = serde_json::from_str(&raw)?;

        // Return the parsed object
        Ok(parsed)
    }

    /// Writes the cache by stringifing the JSON object
    ///
    /// Arguments:
    /// * data - The data that needs to be saved
    ///
    /// # Examples
    ///
    /// ```no_run
    /// use takoyaki_core::Cache;
    /// use serde_json::Value;
    ///
    /// let cache = Cache::new("my_plugin");
    /// let parsed = cache.write(Value::Bool(true));
    /// ```
    pub fn write<T>(&self, data: &T) -> Result<(), TakoyakiError>
    where
        T: Serialize,
    {
        // Make sure that the parent directory exists
        create_dir_all(self.cache_path.parent().unwrap())?;

        // Create a new file
        let mut cache_file = File::create(&self.cache_path)?;

        // Parse the data to a string
        let parsed = serde_json::to_string(data).unwrap();

        // Write the parsed content to the file
        cache_file.write_all(parsed.as_bytes())?;

        // Ok!
        Ok(())
    }
}