use std::future::Future; use std::marker::PhantomData; use std::pin::Pin; use std::task::{Context, Poll}; use futures::future::{ok, Ready}; use crate::{IntoService, IntoServiceFactory, Service, ServiceFactory}; /// Create `ServiceFactory` for function that can act as a `Service` pub fn service_fn( f: F, ) -> FnServiceFactory where F: FnMut(Req) -> Fut + Clone, Fut: Future>, { FnServiceFactory::new(f) } pub fn service_fn2(f: F) -> FnService where F: FnMut(Req) -> Fut, Fut: Future>, { FnService::new(f) } /// Create `ServiceFactory` for function that can produce services pub fn factory_fn(f: F) -> FnServiceNoConfig where Srv: Service, F: Fn() -> Fut, Fut: Future>, { FnServiceNoConfig::new(f) } /// Create `ServiceFactory` for function that can produce services with configuration pub fn factory_fn_cfg(f: F) -> FnServiceConfig where F: Fn(&Cfg) -> Fut, Fut: Future>, Srv: Service, { FnServiceConfig::new(f) } pub struct FnService where F: FnMut(Req) -> Fut, Fut: Future>, { f: F, _t: PhantomData, } impl FnService where F: FnMut(Req) -> Fut, Fut: Future>, { pub(crate) fn new(f: F) -> Self { Self { f, _t: PhantomData } } } impl Clone for FnService where F: FnMut(Req) -> Fut + Clone, Fut: Future>, { fn clone(&self) -> Self { Self::new(self.f.clone()) } } impl Service for FnService where F: FnMut(Req) -> Fut, Fut: Future>, { type Request = Req; type Response = Res; type Error = Err; type Future = Fut; fn poll_ready(&mut self, _: &mut Context<'_>) -> Poll> { Poll::Ready(Ok(())) } fn call(&mut self, req: Req) -> Self::Future { (self.f)(req) } } impl IntoService> for F where F: FnMut(Req) -> Fut, Fut: Future>, { fn into_service(self) -> FnService { FnService::new(self) } } pub struct FnServiceFactory where F: FnMut(Req) -> Fut, Fut: Future>, { f: F, _t: PhantomData<(Req, Cfg)>, } impl FnServiceFactory where F: FnMut(Req) -> Fut + Clone, Fut: Future>, { fn new(f: F) -> Self { FnServiceFactory { f, _t: PhantomData } } } impl Clone for FnServiceFactory where F: FnMut(Req) -> Fut + Clone, Fut: Future>, { fn clone(&self) -> Self { Self::new(self.f.clone()) } } impl ServiceFactory for FnServiceFactory where F: FnMut(Req) -> Fut + Clone, Fut: Future>, { type Request = Req; type Response = Res; type Error = Err; type Config = Cfg; type Service = FnService; type InitError = (); type Future = Ready>; fn new_service(&self, _: &Cfg) -> Self::Future { ok(FnService::new(self.f.clone())) } } impl IntoServiceFactory> for F where F: Fn(Req) -> Fut + Clone, Fut: Future>, { fn into_factory(self) -> FnServiceFactory { FnServiceFactory::new(self) } } /// Convert `Fn(&Config) -> Future` fn to NewService pub struct FnServiceConfig where F: Fn(&Cfg) -> Fut, Fut: Future>, Srv: Service, { f: F, _t: PhantomData<(Fut, Cfg, Srv, Err)>, } impl FnServiceConfig where F: Fn(&Cfg) -> Fut, Fut: Future>, Srv: Service, { fn new(f: F) -> Self { FnServiceConfig { f, _t: PhantomData } } } impl ServiceFactory for FnServiceConfig where F: Fn(&Cfg) -> Fut, Fut: Future> + Unpin, Srv: Service, { type Request = Srv::Request; type Response = Srv::Response; type Error = Srv::Error; type Config = Cfg; type Service = Srv; type InitError = Err; type Future = NewServiceFnConfigFut; fn new_service(&self, cfg: &Cfg) -> Self::Future { NewServiceFnConfigFut { fut: (self.f)(cfg), _t: PhantomData, } } } pub struct NewServiceFnConfigFut where R: Future> + Unpin, S: Service, { fut: R, _t: PhantomData<(S,)>, } impl Unpin for NewServiceFnConfigFut where R: Future> + Unpin, S: Service, { } impl Future for NewServiceFnConfigFut where R: Future> + Unpin, S: Service, { type Output = Result; fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { Pin::new(&mut self.get_mut().fut).poll(cx) } } /// Converter for `Fn() -> Future` fn pub struct FnServiceNoConfig where F: Fn() -> R, S: Service, R: Future>, { f: F, _t: PhantomData, } impl FnServiceNoConfig where F: Fn() -> R, R: Future>, S: Service, { fn new(f: F) -> Self { Self { f, _t: PhantomData } } } impl ServiceFactory for FnServiceNoConfig where F: Fn() -> R, R: Future>, S: Service, { type Request = S::Request; type Response = S::Response; type Error = S::Error; type Service = S; type Config = C; type InitError = E; type Future = R; fn new_service(&self, _: &C) -> Self::Future { (self.f)() } } impl Clone for FnServiceNoConfig where F: Fn() -> R + Clone, R: Future>, S: Service, { fn clone(&self) -> Self { Self::new(self.f.clone()) } } impl IntoServiceFactory> for F where F: Fn() -> R, R: Future>, S: Service, { fn into_factory(self) -> FnServiceNoConfig { FnServiceNoConfig::new(self) } }