Skip to main content

tower_http_cache_plus/cache/middleware/responses/
cached.rs

1use super::super::super::{cache::*, configuration::*, key::*, response::*};
2
3use {
4    http::*,
5    http_body::*,
6    kutil::{
7        http::transcoding::*,
8        std::{error::*, immutable::*},
9        transcoding::*,
10    },
11};
12
13//
14// ToTranscodingResponse
15//
16
17/// To transcoding response.
18#[allow(async_fn_in_trait)]
19pub trait ToTranscodingResponse {
20    /// To a [Response] with a [TranscodingBody].
21    ///
22    /// Will update the cache if we are modified.
23    ///
24    /// If we encounter an error will return a response with [StatusCode::INTERNAL_SERVER_ERROR].
25    async fn to_transcoding_response<ResponseBodyT, CacheT, CacheKeyT>(
26        self,
27        encoding: &Encoding,
28        is_new: bool,
29        cache: CacheT,
30        key: CacheKeyT,
31        configuration: &EncodingConfiguration,
32    ) -> Response<TranscodingBody<ResponseBodyT>>
33    where
34        ResponseBodyT: 'static + Body + From<ImmutableBytes> + Send + Unpin,
35        ResponseBodyT::Data: From<ImmutableBytes> + Send,
36        ResponseBodyT::Error: Into<CapturedError>,
37        CacheT: Cache<CacheKeyT>,
38        CacheKeyT: CacheKey;
39}
40
41impl ToTranscodingResponse for CachedResponseRef {
42    /// To a [Response] with a [TranscodingBody].
43    ///
44    /// Will update the cache if we are modified.
45    ///
46    /// If we encounter an error will return a response with [StatusCode::INTERNAL_SERVER_ERROR].
47    async fn to_transcoding_response<ResponseBodyT, CacheT, CacheKeyT>(
48        self,
49        encoding: &Encoding,
50        is_new: bool,
51        cache: CacheT,
52        key: CacheKeyT,
53        configuration: &EncodingConfiguration,
54    ) -> Response<TranscodingBody<ResponseBodyT>>
55    where
56        ResponseBodyT: 'static + Body + From<ImmutableBytes> + Send + Unpin,
57        ResponseBodyT::Data: From<ImmutableBytes>,
58        ResponseBodyT::Error: Into<CapturedError>,
59        CacheT: Cache<CacheKeyT>,
60        CacheKeyT: CacheKey,
61    {
62        match self.to_response(&encoding, configuration).await {
63            Ok((response, modified)) => {
64                if is_new {
65                    cache.put(key, self).await;
66                } else if let Some(modified) = modified {
67                    // A new CachedResponse should already contain our encoding
68                    // and thus never cause modification!
69                    assert!(!is_new);
70
71                    cache.put(key, modified.into()).await;
72                }
73
74                response
75            }
76
77            Err(error) => {
78                tracing::error!("could not create response from cache: {} {}", key, error);
79                error_transcoding_response()
80            }
81        }
82    }
83}