use std::marker::PhantomData; use futures::future::{ok, Future, FutureResult}; use futures::{try_ready, Async, IntoFuture, Poll}; use crate::{IntoNewService, IntoService, NewService, Service}; /// Create `NewService` for function that can act as a Service pub fn service_fn(f: F) -> NewServiceFn where F: FnMut(Req) -> Out + Clone, Out: IntoFuture, { NewServiceFn::new(f) } /// Create `NewService` for function that can produce services pub fn new_service_fn(f: F) -> FnNewServiceNoConfig where F: Fn() -> R, R: IntoFuture, R::Item: IntoService, S: Service, { FnNewServiceNoConfig::new(f) } /// Create `NewService` for function that can produce services with configuration pub fn new_service_cfg(f: F) -> FnNewServiceConfig where F: Fn(&C) -> R, R: IntoFuture, R::Item: IntoService, S: Service, { FnNewServiceConfig::new(f) } pub struct ServiceFn where F: FnMut(Req) -> Out, Out: IntoFuture, { f: F, _t: PhantomData, } impl ServiceFn where F: FnMut(Req) -> Out, Out: IntoFuture, { pub(crate) fn new(f: F) -> Self { ServiceFn { f, _t: PhantomData } } } impl Clone for ServiceFn where F: FnMut(Req) -> Out + Clone, Out: IntoFuture, { fn clone(&self) -> Self { ServiceFn::new(self.f.clone()) } } impl Service for ServiceFn where F: FnMut(Req) -> Out, Out: IntoFuture, { type Request = Req; type Response = Out::Item; type Error = Out::Error; type Future = Out::Future; fn poll_ready(&mut self) -> Poll<(), Self::Error> { Ok(Async::Ready(())) } fn call(&mut self, req: Req) -> Self::Future { (self.f)(req).into_future() } } impl IntoService> for F where F: FnMut(Req) -> Out, Out: IntoFuture, { fn into_service(self) -> ServiceFn { ServiceFn::new(self) } } pub struct NewServiceFn where F: FnMut(Req) -> Out, Out: IntoFuture, { f: F, _t: PhantomData<(Req, Cfg)>, } impl NewServiceFn where F: FnMut(Req) -> Out + Clone, Out: IntoFuture, { pub(crate) fn new(f: F) -> Self { NewServiceFn { f, _t: PhantomData } } } impl Clone for NewServiceFn where F: FnMut(Req) -> Out + Clone, Out: IntoFuture, { fn clone(&self) -> Self { NewServiceFn::new(self.f.clone()) } } impl NewService for NewServiceFn where F: FnMut(Req) -> Out + Clone, Out: IntoFuture, { type Request = Req; type Response = Out::Item; type Error = Out::Error; type Config = Cfg; type Service = ServiceFn; type InitError = (); type Future = FutureResult; fn new_service(&self, _: &Cfg) -> Self::Future { ok(ServiceFn::new(self.f.clone())) } } impl IntoService> for NewServiceFn where F: FnMut(Req) -> Out + Clone, Out: IntoFuture, { fn into_service(self) -> ServiceFn { ServiceFn::new(self.f.clone()) } } impl IntoNewService> for F where F: Fn(Req) -> Out + Clone, Out: IntoFuture, { fn into_new_service(self) -> NewServiceFn { NewServiceFn::new(self) } } /// Convert `Fn(&Config) -> Future` fn to NewService pub struct FnNewServiceConfig where F: Fn(&C) -> R, R: IntoFuture, R::Item: IntoService, S: Service, { f: F, _t: PhantomData<(C, R, S, E)>, } impl FnNewServiceConfig where F: Fn(&C) -> R, R: IntoFuture, R::Item: IntoService, S: Service, { pub fn new(f: F) -> Self { FnNewServiceConfig { f, _t: PhantomData } } } impl NewService for FnNewServiceConfig where F: Fn(&C) -> R, R: IntoFuture, R::Item: IntoService, S: Service, { type Request = S::Request; type Response = S::Response; type Error = S::Error; type Config = C; type Service = S; type InitError = E; type Future = FnNewServiceConfigFut; fn new_service(&self, cfg: &C) -> Self::Future { FnNewServiceConfigFut { fut: (self.f)(cfg).into_future(), _t: PhantomData, } } } pub struct FnNewServiceConfigFut where R: IntoFuture, R::Item: IntoService, S: Service, { fut: R::Future, _t: PhantomData<(S,)>, } impl Future for FnNewServiceConfigFut where R: IntoFuture, R::Item: IntoService, S: Service, { type Item = S; type Error = R::Error; fn poll(&mut self) -> Poll { Ok(Async::Ready(try_ready!(self.fut.poll()).into_service())) } } impl Clone for FnNewServiceConfig where F: Fn(&C) -> R + Clone, R: IntoFuture, R::Item: IntoService, S: Service, { fn clone(&self) -> Self { Self::new(self.f.clone()) } } /// Converter for `Fn() -> Future` fn pub struct FnNewServiceNoConfig where F: Fn() -> R, R: IntoFuture, S: Service, { f: F, _t: PhantomData, } impl FnNewServiceNoConfig where F: Fn() -> R, R: IntoFuture, S: Service, { pub fn new(f: F) -> Self { FnNewServiceNoConfig { f, _t: PhantomData } } } impl NewService for FnNewServiceNoConfig where F: Fn() -> R, R: IntoFuture, 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::Future; fn new_service(&self, _: &C) -> Self::Future { (self.f)().into_future() } } impl Clone for FnNewServiceNoConfig where F: Fn() -> R + Clone, R: IntoFuture, S: Service, { fn clone(&self) -> Self { Self::new(self.f.clone()) } } impl IntoNewService> for F where F: Fn() -> R, R: IntoFuture, S: Service, { fn into_new_service(self) -> FnNewServiceNoConfig { FnNewServiceNoConfig::new(self) } }