use std::marker; use futures::{Async, Future, IntoFuture, Poll}; use super::{IntoNewService, NewService, Service}; pub struct FnStateService where F: Fn(&mut S, Req) -> Fut, Fut: IntoFuture, { f: F, state: S, _t: marker::PhantomData<(Req, Resp, Err)>, } impl FnStateService where F: Fn(&mut S, Req) -> Fut, Fut: IntoFuture, { pub fn new(state: S, f: F) -> Self { FnStateService { f, state, _t: marker::PhantomData, } } } impl Clone for FnStateService where S: Clone, F: Fn(&mut S, Req) -> Fut + Clone, Fut: IntoFuture, { fn clone(&self) -> Self { FnStateService { f: self.f.clone(), state: self.state.clone(), _t: marker::PhantomData, } } } impl Service for FnStateService where F: Fn(&mut S, Req) -> Fut, Fut: IntoFuture, { type Request = Req; type Response = Resp; type Error = Err; type Future = Fut::Future; fn poll_ready(&mut self) -> Poll<(), Self::Error> { Ok(Async::Ready(())) } fn call(&mut self, req: Req) -> Self::Future { (self.f)(&mut self.state, req).into_future() } } /// `NewService` for state and handler functions pub struct FnStateNewService { f: F1, state: F2, _t: marker::PhantomData<(S, Req, Resp, Err1, Err2, Fut1, Fut2)>, } impl FnStateNewService { fn new(f: F1, state: F2) -> Self { FnStateNewService { f, state, _t: marker::PhantomData, } } } impl NewService for FnStateNewService where S: 'static, F1: Fn(&mut S, Req) -> Fut1 + Clone + 'static, F2: Fn() -> Fut2, Fut1: IntoFuture + 'static, Fut2: IntoFuture + 'static, Req: 'static, Resp: 'static, Err1: 'static, Err2: 'static, { type Request = Req; type Response = Resp; type Error = Err1; type Service = FnStateService; type InitError = Err2; type Future = Box>; fn new_service(&self) -> Self::Future { let f = self.f.clone(); Box::new( (self.state)() .into_future() .and_then(move |state| Ok(FnStateService::new(state, f))), ) } } impl IntoNewService> for (F1, F2) where S: 'static, F1: Fn(&mut S, Req) -> Fut1 + Clone + 'static, F2: Fn() -> Fut2, Fut1: IntoFuture + 'static, Fut2: IntoFuture + 'static, Req: 'static, Resp: 'static, Err1: 'static, Err2: 'static, { fn into_new_service( self, ) -> FnStateNewService { FnStateNewService::new(self.0, self.1) } } impl Clone for FnStateNewService where F1: Fn(&mut S, Req) -> Fut1 + Clone + 'static, F2: Fn() -> Fut2 + Clone, Fut1: IntoFuture, Fut2: IntoFuture, { fn clone(&self) -> Self { Self::new(self.f.clone(), self.state.clone()) } }