use std::net; use futures::future::{err, ok}; use futures::{Future, Poll}; use tokio_reactor::Handle; use tokio_tcp::TcpStream; use service::{NewService, Service}; pub enum ServerMessage { Connect(net::TcpStream), Shutdown, ForceShutdown, } pub(crate) type BoxedServerService = Box< Service< Request = ServerMessage, Response = (), Error = (), Future = Box>, >, >; pub(crate) struct ServerService { service: T, } impl ServerService { fn new(service: T) -> Self { ServerService { service } } } impl Service for ServerService where T: Service, T::Future: 'static, T::Error: 'static, { type Request = ServerMessage; type Response = (); type Error = (); type Future = Box>; fn poll_ready(&mut self) -> Poll<(), Self::Error> { self.service.poll_ready().map_err(|_| ()) } fn call(&mut self, req: ServerMessage) -> Self::Future { match req { ServerMessage::Connect(stream) => { let stream = TcpStream::from_std(stream, &Handle::default()).map_err(|e| { error!("Can not convert to an async tcp stream: {}", e); }); if let Ok(stream) = stream { Box::new(self.service.call(stream)) } else { Box::new(err(())) } } _ => Box::new(ok(())), } } } pub(crate) struct ServerNewService { inner: F, } impl ServerNewService where F: ServerServiceFactory, { pub(crate) fn create(inner: F) -> Box { Box::new(Self { inner }) } } pub(crate) trait InternalServerServiceFactory: Send { fn clone_factory(&self) -> Box; fn create(&self) -> Box>; } impl InternalServerServiceFactory for ServerNewService where F: ServerServiceFactory, { fn clone_factory(&self) -> Box { Box::new(Self { inner: self.inner.clone(), }) } fn create(&self) -> Box> { Box::new(self.inner.create().new_service().map(move |inner| { let service: BoxedServerService = Box::new(ServerService::new(inner)); service })) } } impl InternalServerServiceFactory for Box { fn clone_factory(&self) -> Box { self.as_ref().clone_factory() } fn create(&self) -> Box> { self.as_ref().create() } } pub trait ServerServiceFactory: Send + Clone + 'static { type NewService: NewService; fn create(&self) -> Self::NewService; } impl ServerServiceFactory for F where F: Fn() -> T + Send + Clone + 'static, T: NewService, { type NewService = T; fn create(&self) -> T { (self)() } }