//! Caching utilities use std::mem::{self, MaybeUninit}; use std::error; use std::borrow::Borrow; use std::sync::RwLock; /// A trait for objects that can cache an operation in themselves pub trait Cache { type Cached; /// Compute the `Cached` value. fn cache(&self) -> Self::Cached; } /// A value that might be cached or not. #[derive(Debug, Clone, PartialEq, Eq, Hash, Ord, PartialOrd)] pub enum MaybeCached { Uncached(T), Cached(T::Cached), } impl MaybeCached { /// Cache the operation #[inline] pub fn cache(&mut self) { match self { Self::Uncached(val) => *self = Self::Cached(val.cache()), _ => (), } } /// Has this value been cached pub fn is_cached(&self) -> bool { if let Self::Cached(_) = &self { true } else { false } } /// Consume into the cached operation #[inline] pub fn into_cached(mut self) -> Self { self.cache(); self } /// Compute the operation #[inline] pub fn compute(self) -> T::Cached { match self { Self::Cached(c) => c, Self::Uncached(val) => val.cache(), } } } impl Cache for F where F: Fn() -> T { type Cached = T; #[inline] fn cache(&self) -> Self::Cached { self() } } /* #[derive(Debug)] pub struct LazyCached(RwLock>, T); impl LazyCached { pub fn new(value: T) -> Self { Self(RwLock::new(None), value) } } */ //TODO:idfk..