kutil_http/cache/middleware/responses/
cached.rs

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