use std::future::Future; use std::marker::PhantomData; use std::pin::Pin; use std::task::{Context, Poll}; use super::ServiceFactory; /// `MapInitErr` service combinator pub struct MapInitErr { a: A, f: F, e: PhantomData, } impl MapInitErr where A: ServiceFactory, F: Fn(A::InitError) -> E, { /// Create new `MapInitErr` combinator pub(crate) fn new(a: A, f: F) -> Self { Self { a, f, e: PhantomData, } } } impl Clone for MapInitErr where A: Clone, F: Clone, { fn clone(&self) -> Self { Self { a: self.a.clone(), f: self.f.clone(), e: PhantomData, } } } impl ServiceFactory for MapInitErr where A: ServiceFactory, F: Fn(A::InitError) -> E + Clone, { type Request = A::Request; type Response = A::Response; type Error = A::Error; type Config = A::Config; type Service = A::Service; type InitError = E; type Future = MapInitErrFuture; fn new_service(&self, cfg: A::Config) -> Self::Future { MapInitErrFuture::new(self.a.new_service(cfg), self.f.clone()) } } #[pin_project::pin_project] pub struct MapInitErrFuture where A: ServiceFactory, F: Fn(A::InitError) -> E, { f: F, #[pin] fut: A::Future, } impl MapInitErrFuture where A: ServiceFactory, F: Fn(A::InitError) -> E, { fn new(fut: A::Future, f: F) -> Self { MapInitErrFuture { f, fut } } } impl Future for MapInitErrFuture where A: ServiceFactory, F: Fn(A::InitError) -> E, { type Output = Result; fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { let this = self.project(); this.fut.poll(cx).map_err(this.f) } }