tower_resilience_cache/
layer.rs

1use crate::{Cache, CacheConfig};
2use std::hash::Hash;
3use std::sync::Arc;
4use tower::Layer;
5
6/// A Tower [`Layer`] that applies response caching to a service.
7///
8/// This layer wraps a service with a [`Cache`] middleware that stores
9/// successful responses and returns cached values for subsequent requests
10/// with the same key.
11///
12/// # Examples
13///
14/// ```
15/// use tower_resilience_cache::CacheLayer;
16/// use tower::ServiceBuilder;
17/// use std::time::Duration;
18///
19/// # async fn example() {
20/// let cache_layer = CacheLayer::builder()
21///     .max_size(100)
22///     .ttl(Duration::from_secs(60))
23///     .key_extractor(|req: &String| req.clone())
24///     .build();
25///
26/// let service = ServiceBuilder::new()
27///     .layer(cache_layer)
28///     .service(my_service());
29/// # }
30/// # fn my_service() -> impl tower::Service<String, Response = String, Error = std::io::Error> {
31/// #     tower::service_fn(|req: String| async move { Ok::<_, std::io::Error>(req) })
32/// # }
33/// ```
34#[derive(Clone)]
35pub struct CacheLayer<Req, K> {
36    config: Arc<CacheConfig<Req, K>>,
37}
38
39impl<Req, K> CacheLayer<Req, K>
40where
41    K: Hash + Eq + Clone + Send + 'static,
42{
43    /// Creates a new `CacheLayer` with the given configuration.
44    pub fn new(config: CacheConfig<Req, K>) -> Self {
45        Self {
46            config: Arc::new(config),
47        }
48    }
49
50    /// Creates a new builder for configuring a cache layer.
51    ///
52    /// # Examples
53    ///
54    /// ```
55    /// use tower_resilience_cache::CacheLayer;
56    /// use std::time::Duration;
57    ///
58    /// let layer = CacheLayer::builder()
59    ///     .max_size(100)
60    ///     .ttl(Duration::from_secs(60))
61    ///     .key_extractor(|req: &String| req.clone())
62    ///     .build();
63    /// ```
64    pub fn builder() -> crate::CacheConfigBuilder<Req, K> {
65        crate::CacheConfigBuilder::new()
66    }
67}
68
69impl<S, Req, K> Layer<S> for CacheLayer<Req, K>
70where
71    K: Hash + Eq + Clone + Send + 'static,
72    S: tower::Service<Req>,
73    S::Response: Clone + Send + 'static,
74{
75    type Service = Cache<S, Req, K, S::Response>;
76
77    fn layer(&self, service: S) -> Self::Service {
78        Cache::new(service, Arc::clone(&self.config))
79    }
80}