rama_http/layer/classify/
map_failure_class.rs

1use super::{ClassifiedResponse, ClassifyEos, ClassifyResponse};
2use crate::{HeaderMap, Response};
3use std::fmt;
4
5/// Response classifier that transforms the failure class of some other
6/// classifier.
7///
8/// Created with [`ClassifyResponse::map_failure_class`] or
9/// [`ClassifyEos::map_failure_class`].
10pub struct MapFailureClass<C, F> {
11    inner: C,
12    f: F,
13}
14
15impl<C, F> MapFailureClass<C, F> {
16    pub(super) fn new(classify: C, f: F) -> Self {
17        Self { inner: classify, f }
18    }
19}
20
21impl<C, F> fmt::Debug for MapFailureClass<C, F>
22where
23    C: fmt::Debug,
24    F: fmt::Debug,
25{
26    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
27        f.debug_struct("MapFailureClass")
28            .field("inner", &self.inner)
29            .field("f", &self.f)
30            .finish()
31    }
32}
33
34impl<C, F> Clone for MapFailureClass<C, F>
35where
36    C: Clone,
37    F: Clone,
38{
39    fn clone(&self) -> Self {
40        Self {
41            inner: self.inner.clone(),
42            f: self.f.clone(),
43        }
44    }
45}
46
47impl<C, F, NewClass> ClassifyResponse for MapFailureClass<C, F>
48where
49    C: ClassifyResponse + Send + Sync + 'static,
50    F: FnOnce(C::FailureClass) -> NewClass + Send + Sync + 'static,
51    NewClass: Send + Sync + 'static,
52{
53    type FailureClass = NewClass;
54    type ClassifyEos = MapFailureClass<C::ClassifyEos, F>;
55
56    fn classify_response<B>(
57        self,
58        res: &Response<B>,
59    ) -> ClassifiedResponse<Self::FailureClass, Self::ClassifyEos> {
60        match self.inner.classify_response(res) {
61            ClassifiedResponse::Ready(result) => ClassifiedResponse::Ready(result.map_err(self.f)),
62            ClassifiedResponse::RequiresEos(classify_eos) => {
63                let mapped_classify_eos = MapFailureClass::new(classify_eos, self.f);
64                ClassifiedResponse::RequiresEos(mapped_classify_eos)
65            }
66        }
67    }
68
69    fn classify_error<E>(self, error: &E) -> Self::FailureClass
70    where
71        E: std::fmt::Display,
72    {
73        (self.f)(self.inner.classify_error(error))
74    }
75}
76
77impl<C, F, NewClass> ClassifyEos for MapFailureClass<C, F>
78where
79    C: ClassifyEos,
80    F: FnOnce(C::FailureClass) -> NewClass,
81{
82    type FailureClass = NewClass;
83
84    fn classify_eos(self, trailers: Option<&HeaderMap>) -> Result<(), Self::FailureClass> {
85        self.inner.classify_eos(trailers).map_err(self.f)
86    }
87
88    fn classify_error<E>(self, error: &E) -> Self::FailureClass
89    where
90        E: std::fmt::Display,
91    {
92        (self.f)(self.inner.classify_error(error))
93    }
94}