use std::hash::Hash;
use crate::{noop::Noop, Cache, CacheKey, CacheStrategy, CompressionStrategy, Result};
#[derive(Debug, Default)]
pub struct CacheBuilder;
pub struct CacheBuilderWithStrategy<S> {
strategy: S,
}
impl<S> Default for CacheBuilderWithStrategy<S>
where
S: Default + CacheStrategy,
{
fn default() -> Self {
CacheBuilderWithStrategy {
strategy: S::default(),
}
}
}
pub struct CacheBuilderWithCompression<C> {
compressor: C,
}
impl<C> Default for CacheBuilderWithCompression<C>
where
C: Default + CompressionStrategy,
{
fn default() -> Self {
CacheBuilderWithCompression {
compressor: C::default(),
}
}
}
pub struct CacheBuilderWithCompressionAndStrategy<S, C> {
strategy: S,
compressor: C,
}
impl<S, C> Default for CacheBuilderWithCompressionAndStrategy<S, C>
where
S: Default + CacheStrategy,
C: Default + CompressionStrategy,
{
fn default() -> Self {
CacheBuilderWithCompressionAndStrategy {
strategy: S::default(),
compressor: C::default(),
}
}
}
impl CacheBuilder {
pub fn with_strategy<S>(self, strategy: S) -> CacheBuilderWithStrategy<S>
where
S: CacheStrategy,
{
CacheBuilderWithStrategy { strategy }
}
pub fn with_compression<C>(self, compressor: C) -> CacheBuilderWithCompression<C>
where
C: CompressionStrategy,
{
CacheBuilderWithCompression { compressor }
}
}
impl<C> CacheBuilderWithCompression<C> {
pub fn with_strategy<S>(self, strategy: S) -> CacheBuilderWithCompressionAndStrategy<S, C> {
{
CacheBuilderWithCompressionAndStrategy {
strategy,
compressor: self.compressor,
}
}
}
}
impl<S> CacheBuilderWithStrategy<S>
where
S: CacheStrategy + Send,
{
pub fn with_compression<C>(self, compressor: C) -> CacheBuilderWithCompressionAndStrategy<S, C>
where
C: CompressionStrategy,
{
CacheBuilderWithCompressionAndStrategy {
strategy: self.strategy,
compressor,
}
}
pub async fn build<K>(self) -> Result<Cache<K, S, Noop>>
where
K: CacheKey + Eq + Hash + Sync + Send,
{
Cache::new(self.strategy, None).await
}
}
impl<S, C> CacheBuilderWithCompressionAndStrategy<S, C>
where
S: CacheStrategy + Send,
C: CompressionStrategy,
{
pub async fn build<K>(self) -> Result<Cache<K, S, C>>
where
K: CacheKey + Eq + Hash + Sync + Send,
C: CompressionStrategy + Sync + Send,
{
Cache::new(self.strategy, Some(self.compressor)).await
}
}
#[cfg(test)]
mod tests {
use crate::{async_test, noop::Noop};
use super::*;
async_test! {
async fn test_default() {
_ = CacheBuilder::default();
}
async fn test_type_aliased() {
type NoopCacheBuilder = CacheBuilderWithStrategy<Noop>;
_ = NoopCacheBuilder::default().build::<String>();
}
async fn test_key_inference() {
let mut cache = CacheBuilder::default().with_strategy(Noop).build().await.unwrap();
cache.put("test".to_string(), vec![]).await.unwrap();
}
}
}