You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

85 lines
1.5 KiB

//! 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<T: Cache>
{
Uncached(T),
Cached(T::Cached),
}
impl<T: Cache> MaybeCached<T>
{
/// 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<F, T> Cache for F
where F: Fn() -> T
{
type Cached = T;
#[inline] fn cache(&self) -> Self::Cached
{
self()
}
}
/*
#[derive(Debug)]
pub struct LazyCached<T: Cache + ?Sized>(RwLock<Option<T::Cached>>, T);
impl<T: Cache> LazyCached<T>
{
pub fn new(value: T) -> Self
{
Self(RwLock::new(None), value)
}
}
*/
//TODO:idfk..