tower_http/classify/
map_failure_class.rs

1use super::{ClassifiedResponse, ClassifyEos, ClassifyResponse};
2use http::{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`].
10#[derive(Clone, Copy)]
11pub struct MapFailureClass<C, F> {
12    inner: C,
13    f: F,
14}
15
16impl<C, F> MapFailureClass<C, F> {
17    pub(super) fn new(classify: C, f: F) -> Self {
18        Self { inner: classify, f }
19    }
20}
21
22impl<C, F> fmt::Debug for MapFailureClass<C, F>
23where
24    C: 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", &format_args!("{}", std::any::type_name::<F>()))
30            .finish()
31    }
32}
33
34impl<C, F, NewClass> ClassifyResponse for MapFailureClass<C, F>
35where
36    C: ClassifyResponse,
37    F: FnOnce(C::FailureClass) -> NewClass,
38{
39    type FailureClass = NewClass;
40    type ClassifyEos = MapFailureClass<C::ClassifyEos, F>;
41
42    fn classify_response<B>(
43        self,
44        res: &Response<B>,
45    ) -> ClassifiedResponse<Self::FailureClass, Self::ClassifyEos> {
46        match self.inner.classify_response(res) {
47            ClassifiedResponse::Ready(result) => ClassifiedResponse::Ready(result.map_err(self.f)),
48            ClassifiedResponse::RequiresEos(classify_eos) => {
49                let mapped_classify_eos = MapFailureClass::new(classify_eos, self.f);
50                ClassifiedResponse::RequiresEos(mapped_classify_eos)
51            }
52        }
53    }
54
55    fn classify_error<E>(self, error: &E) -> Self::FailureClass
56    where
57        E: std::fmt::Display + 'static,
58    {
59        (self.f)(self.inner.classify_error(error))
60    }
61}
62
63impl<C, F, NewClass> ClassifyEos for MapFailureClass<C, F>
64where
65    C: ClassifyEos,
66    F: FnOnce(C::FailureClass) -> NewClass,
67{
68    type FailureClass = NewClass;
69
70    fn classify_eos(self, trailers: Option<&HeaderMap>) -> Result<(), Self::FailureClass> {
71        self.inner.classify_eos(trailers).map_err(self.f)
72    }
73
74    fn classify_error<E>(self, error: &E) -> Self::FailureClass
75    where
76        E: std::fmt::Display + 'static,
77    {
78        (self.f)(self.inner.classify_error(error))
79    }
80}