takoyaki_core 1.2.0

Core package to build plugins for takoyaki
Documentation
// Import dependencies
use crate::{Cache, TakoyakiError};
use reqwest::RequestBuilder;
use serde::{Deserialize, Serialize};

/// Handles where the data should be retrieved from cache or from request
/// In case of fetching, it populates the cache with the new data
pub struct State {
    builder: RequestBuilder,
    cache: Cache,
}

// Add functions
impl State {
    /// Creates a new instance of the State
    ///
    /// ## Arguments
    ///
    /// * `builder` - Instance of `reqwest::RequestBuilder`
    /// * `cache` - Cache instance
    ///
    /// ## Examples:
    ///
    /// ```
    /// use takoyaki_core::{State, Cache};
    ///
    /// let state = State::new(
    ///     reqwest::Client::new().get(""),
    ///     Cache::new("my_plugin")    
    /// );
    /// ```
    pub fn new(builder: RequestBuilder, cache: Cache) -> Self {
        Self { builder, cache }
    }

    /// Resolves the cache by either reading it from cache or fetching
    ///
    /// If the cache is not found, the new fetched data is written as a new cache
    ///
    /// ## Examples
    ///
    /// ```no_run
    /// use takoyaki_core::{State, Cache};
    ///
    /// let state = State::new(
    ///     reqwest::Client::new().get(""),
    ///     Cache::new("my_plugin")    
    /// );
    ///
    /// let data = state.resolve<serde_json::Value>();
    /// ```
    pub async fn resolve<T>(&self) -> Result<T, TakoyakiError>
    where
        T: Serialize + for<'de> Deserialize<'de> + std::fmt::Debug,
    {
        // Check if cache is valid
        if !self.cache.is_corrupted()? {
            return self.cache.get();
        }

        // Make request
        let response: T = self
            .builder
            .try_clone()
            .unwrap()
            .send()
            .await?
            .json()
            .await?;

        // Populate cache
        self.cache.write(&response)?;

        // Return the new data
        Ok(response)
    }
}