use super::{ClassifiedResponse, ClassifyEos, ClassifyResponse}; use http::{HeaderMap, Response}; use std::fmt; /// Response classifier that transforms the failure class of some other /// classifier. /// /// Created with [`ClassifyResponse::map_failure_class`] or /// [`ClassifyEos::map_failure_class`]. #[derive(Clone, Copy)] pub struct MapFailureClass { inner: C, f: F, } impl MapFailureClass { pub(super) fn new(classify: C, f: F) -> Self { Self { inner: classify, f } } } impl fmt::Debug for MapFailureClass where C: fmt::Debug, { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_struct("MapFailureClass") .field("inner", &self.inner) .field("f", &format_args!("{}", std::any::type_name::())) .finish() } } impl ClassifyResponse for MapFailureClass where C: ClassifyResponse, F: FnOnce(C::FailureClass) -> NewClass, { type FailureClass = NewClass; type ClassifyEos = MapFailureClass; fn classify_response( self, res: &Response, ) -> ClassifiedResponse { match self.inner.classify_response(res) { ClassifiedResponse::Ready(result) => ClassifiedResponse::Ready(result.map_err(self.f)), ClassifiedResponse::RequiresEos(classify_eos) => { let mapped_classify_eos = MapFailureClass::new(classify_eos, self.f); ClassifiedResponse::RequiresEos(mapped_classify_eos) } } } fn classify_error(self, error: &E) -> Self::FailureClass where E: std::fmt::Display + 'static, { (self.f)(self.inner.classify_error(error)) } } impl ClassifyEos for MapFailureClass where C: ClassifyEos, F: FnOnce(C::FailureClass) -> NewClass, { type FailureClass = NewClass; fn classify_eos(self, trailers: Option<&HeaderMap>) -> Result<(), Self::FailureClass> { self.inner.classify_eos(trailers).map_err(self.f) } fn classify_error(self, error: &E) -> Self::FailureClass where E: std::fmt::Display + 'static, { (self.f)(self.inner.classify_error(error)) } }