use cachet::{Cache, CacheEntry, CacheOperation, CacheResponse, CacheServiceExt};
use layered::{Layer, Service};
use tick::Clock;
struct LoggingLayer;
impl<S> Layer<S> for LoggingLayer {
type Service = LoggingMiddleware<S>;
fn layer(&self, inner: S) -> Self::Service {
LoggingMiddleware(inner)
}
}
struct LoggingMiddleware<S>(S);
impl<S> Service<CacheOperation<String, String>> for LoggingMiddleware<S>
where
S: Service<CacheOperation<String, String>, Out = Result<CacheResponse<String>, cachet::Error>> + Send + Sync,
{
type Out = Result<CacheResponse<String>, cachet::Error>;
async fn execute(&self, input: CacheOperation<String, String>) -> Self::Out {
let op = match &input {
CacheOperation::Get(_) => "GET",
CacheOperation::Insert(_) => "INSERT",
CacheOperation::Invalidate(_) => "INVALIDATE",
CacheOperation::Clear => "CLEAR",
};
println!("[LOG] {op}");
self.0.execute(input).await
}
}
#[tokio::main]
async fn main() {
let clock = Clock::new_tokio();
let cache = Cache::builder::<String, String>(clock).memory().build();
let logged_cache = LoggingLayer.layer(cache);
logged_cache
.insert("key".to_string(), CacheEntry::new("value".to_string()))
.await
.expect("insert failed");
let value = logged_cache.get(&"key".to_string()).await.expect("get failed");
match value {
Some(e) => println!("get(key): {}", e.value()),
None => println!("get(key): not found"),
}
}