use rom_cache::cache::{CacheMut, CacheRef};
use std::any::Any;
#[cfg_attr(
feature = "secret",
doc = "To avoid entering the password during testing, you can enable `mock` feature. This can always return the **same** Encrypter during **each** test."
)]
pub struct Config<const N: usize> {
cache: rom_cache::Cache<1, N>,
}
impl<const N: usize> Default for Config<N> {
fn default() -> Self {
Self {
cache: rom_cache::Cache::<1, N>::default(),
}
}
}
impl<const N: usize> Config<N> {
pub fn new() -> Self {
Self::default()
}
pub fn get<T>(&self) -> <T as Cacheable<()>>::Ref<'_>
where
T: Cacheable<()> + Any + Send + Sync,
{
T::retrieve(&self.cache)
}
pub fn get_mut<T>(&self) -> <T as Cacheable<()>>::Mut<'_>
where
T: Cacheable<()> + Any + Send + Sync,
{
T::retrieve_mut(&self.cache)
}
pub fn get_many<T>(&self) -> <T as Cacheable<((),)>>::Ref<'_>
where
T: Cacheable<((),)> + Any + Send + Sync,
{
T::retrieve(&self.cache)
}
pub fn get_mut_many<T>(&self) -> <T as Cacheable<((),)>>::Mut<'_>
where
T: Cacheable<((),)> + Any + Send + Sync,
{
T::retrieve_mut(&self.cache)
}
}
pub type CfgRef<'a, T> = CacheRef<'a, T>;
pub type CfgMut<'a, T> = CacheMut<'a, T>;
#[allow(private_bounds, private_interfaces)]
pub trait Cacheable<T> {
type Ref<'a>;
type Mut<'a>;
fn retrieve<const N: usize>(cache: &rom_cache::Cache<1, N>) -> Self::Ref<'_>;
fn retrieve_mut<const N: usize>(cache: &rom_cache::Cache<1, N>) -> Self::Mut<'_>;
}
#[allow(private_bounds, private_interfaces)]
impl<T> Cacheable<()> for T
where
T: rom_cache::Cacheable + Default,
{
type Ref<'a> = CfgRef<'a, T>;
type Mut<'a> = CfgMut<'a, T>;
fn retrieve<const N: usize>(cache: &rom_cache::Cache<1, N>) -> Self::Ref<'_> {
cache.get::<T>().unwrap()
}
fn retrieve_mut<const N: usize>(cache: &rom_cache::Cache<1, N>) -> Self::Mut<'_> {
cache.get_mut::<T>().unwrap()
}
}
macro_rules! impl_cacheable {
($($t: ident),+$(,)?) => {
#[allow(private_bounds, private_interfaces)]
impl<$($t),+> Cacheable<((),)> for ($($t),+,)
where
$($t: Cacheable<()>,)+
{
type Ref<'a> = ($(<$t as Cacheable<()>>::Ref<'a>),+,);
type Mut<'a> = ($(<$t as Cacheable<()>>::Mut<'a>),+,);
fn retrieve<const N: usize>(cache: &rom_cache::Cache<1, N>) -> Self::Ref<'_> {
($(<$t as Cacheable<()>>::retrieve(cache)),+,)
}
fn retrieve_mut<const N: usize>(cache: &rom_cache::Cache<1, N>) -> Self::Mut<'_> {
($(<$t as Cacheable<()>>::retrieve_mut(cache)),+,)
}
}
};
}
impl_cacheable!(T1);
impl_cacheable!(T1, T2);
impl_cacheable!(T1, T2, T3);
impl_cacheable!(T1, T2, T3, T4);
impl_cacheable!(T1, T2, T3, T4, T5);
impl_cacheable!(T1, T2, T3, T4, T5, T6);
impl_cacheable!(T1, T2, T3, T4, T5, T6, T7);
impl_cacheable!(T1, T2, T3, T4, T5, T6, T7, T8);