use crate::__internal_prelude::*;
#[delegatable_trait]
pub trait GenCacheStore:
CacheStore<Key = <Self as GenCacheStore>::Key, Value = <Self as GenCacheStore>::Value>
{
type Key;
type Value;
type Args;
fn gen(
&self,
key: impl Borrow<<Self as GenCacheStore>::Key>,
args: Self::Args,
) -> <Self as GenCacheStore>::Value;
fn get_or_gen(
&self,
key: impl Borrow<<Self as GenCacheStore>::Key>,
args: Self::Args,
) -> <Self as GenCacheStore>::Value;
fn get_or_new(
&mut self,
key: impl Borrow<<Self as GenCacheStore>::Key>,
args: Self::Args,
) -> <Self as GenCacheStore>::Value;
fn gen_new(
&mut self,
key: impl Borrow<<Self as GenCacheStore>::Key>,
args: Self::Args,
) -> <Self as GenCacheStore>::Value;
}
use super::ambassador_impl_CacheStore;
#[derive(Delegate)]
#[delegate(CacheStore, target = "store")]
pub struct GenCacheStoreWrapper<K, V, A, S: CacheStore<Key = K, Value = V>, F: Fn(&K, A) -> V> {
pub store: S,
pub generator: F,
phantom: PhantomData<(K, V, A)>,
}
impl<K, V, A, F: Fn(&K, A) -> V, S: CacheStore<Key = K, Value = V>>
GenCacheStoreWrapper<K, V, A, S, F>
{
pub fn new(store: S, generator: F) -> Self {
Self {
store,
generator,
phantom: PhantomData,
}
}
}
impl<K, V, A, S: CacheStore<Key = K, Value = V>, F: Fn(&K, A) -> V> GenCacheStore
for GenCacheStoreWrapper<K, V, A, S, F>
{
type Key = K;
type Value = V;
type Args = A;
fn gen(&self, key: impl Borrow<K>, args: A) -> V {
(self.generator)(key.borrow(), args)
}
fn get_or_gen(&self, key: impl Borrow<K>, args: A) -> V {
self.store
.get(key.borrow())
.unwrap_or_else(|| self.gen(key, args))
}
fn get_or_new(&mut self, key: impl Borrow<K>, args: A) -> V {
let value = self.get_or_gen(key.borrow(), args);
self.store.set(key, &value);
value
}
fn gen_new(&mut self, key: impl Borrow<K>, args: A) -> V {
let value = self.gen(key.borrow(), args);
self.store.set(key.borrow(), &value);
value
}
}
#[delegatable_trait]
#[allow(clippy::missing_errors_doc)]
pub trait TryGenCacheStore:
TryCacheStore<
Key = <Self as TryGenCacheStore>::Key,
Value = <Self as TryGenCacheStore>::Value,
Error = <Self as TryGenCacheStore>::Error,
>
{
type Key;
type Value;
type Error;
type Args;
fn try_gen(
&self,
key: impl Borrow<<Self as TryGenCacheStore>::Key>,
args: <Self as TryGenCacheStore>::Args,
) -> Result<<Self as TryGenCacheStore>::Value, <Self as TryCacheStore>::Error>;
fn try_get_or_gen(
&self,
key: impl Borrow<<Self as TryGenCacheStore>::Key>,
args: <Self as TryGenCacheStore>::Args,
) -> Result<<Self as TryGenCacheStore>::Value, <Self as TryCacheStore>::Error>;
fn try_get_or_new(
&mut self,
key: impl Borrow<<Self as TryGenCacheStore>::Key>,
args: <Self as TryGenCacheStore>::Args,
) -> Result<<Self as TryGenCacheStore>::Value, <Self as TryCacheStore>::Error>;
fn try_gen_new(
&mut self,
key: impl Borrow<<Self as TryGenCacheStore>::Key>,
args: <Self as TryGenCacheStore>::Args,
) -> Result<<Self as TryGenCacheStore>::Value, <Self as TryCacheStore>::Error>;
}
use crate::ambassador_impl_TryCacheStore;
#[derive(Delegate)]
#[delegate(TryCacheStore, target = "store")]
pub struct TryGenCacheStoreWrapper<
K,
V,
E,
A,
S: TryCacheStore<Key = K, Value = V, Error = E>,
F: Fn(&K, A) -> Result<V, E>,
> {
pub store: S,
pub try_generator: F,
phantom: PhantomData<(K, V, E, A)>,
}
impl<K, V, E, A, F: Fn(&K, A) -> Result<V, E>, S: TryCacheStore<Key = K, Value = V, Error = E>>
TryGenCacheStoreWrapper<K, V, E, A, S, F>
{
pub fn new(store: S, try_generator: F) -> Self {
Self {
store,
try_generator,
phantom: PhantomData,
}
}
}
impl<K, V, E, A, F: Fn(&K, A) -> Result<V, E>, S: TryCacheStore<Key = K, Value = V, Error = E>>
TryGenCacheStore for TryGenCacheStoreWrapper<K, V, E, A, S, F>
{
type Key = K;
type Value = V;
type Error = E;
type Args = A;
fn try_gen(&self, key: impl Borrow<K>, args: A) -> Result<V, E> {
(self.try_generator)(key.borrow(), args)
}
fn try_get_or_gen(&self, key: impl Borrow<K>, args: A) -> Result<V, E> {
let value = self.store.try_get(key.borrow())?;
if let Some(value) = value {
Ok(value)
} else {
self.try_gen(key, args)
}
}
fn try_get_or_new(&mut self, key: impl Borrow<K>, args: A) -> Result<V, E> {
let value = self.try_get_or_gen(key.borrow(), args)?;
self.store.try_set(key, &value)?;
Ok(value)
}
fn try_gen_new(&mut self, key: impl Borrow<K>, args: A) -> Result<V, E> {
let value = self.try_gen(key.borrow(), args)?;
self.store.try_set(key.borrow(), &value)?;
Ok(value)
}
}
impl<K, V, A, T: GenCacheStore<Key = K, Value = V, Args = A>> TryGenCacheStore for T {
type Key = K;
type Value = V;
type Error = core::convert::Infallible;
type Args = A;
fn try_gen(
&self,
key: impl Borrow<<Self as TryGenCacheStore>::Key>,
args: <Self as TryGenCacheStore>::Args,
) -> Result<<Self as TryGenCacheStore>::Value, <Self as TryCacheStore>::Error> {
Ok(self.gen(key, args))
}
fn try_gen_new(
&mut self,
key: impl Borrow<<Self as TryGenCacheStore>::Key>,
args: <Self as TryGenCacheStore>::Args,
) -> Result<<Self as TryGenCacheStore>::Value, <Self as TryCacheStore>::Error> {
Ok(self.gen_new(key, args))
}
fn try_get_or_gen(
&self,
key: impl Borrow<<Self as TryGenCacheStore>::Key>,
args: <Self as TryGenCacheStore>::Args,
) -> Result<<Self as TryGenCacheStore>::Value, <Self as TryCacheStore>::Error> {
Ok(self.get_or_gen(key, args))
}
fn try_get_or_new(
&mut self,
key: impl Borrow<<Self as TryGenCacheStore>::Key>,
args: <Self as TryGenCacheStore>::Args,
) -> Result<<Self as TryGenCacheStore>::Value, <Self as TryCacheStore>::Error> {
Ok(self.get_or_new(key, args))
}
}