use super::server_streaming::{self, ServerStreaming}; use {Request, Response}; use protobuf::server::UnaryService; use futures::{Future, Stream, Poll}; use tower::Service; /// Maps to a unary gRPC service. #[derive(Debug)] pub struct Unary { inner: ServerStreaming, S>, } pub struct ResponseFuture where T: UnaryService, S: Stream, { inner: server_streaming::ResponseFuture, S>, } #[derive(Debug)] pub struct Once { inner: Option, } /// Maps inbound requests #[derive(Debug, Clone)] struct Inner(pub T); struct InnerFuture(T); // ===== impl Unary ===== impl Unary where T: UnaryService, S: Stream, { /// Return a new `Unary` gRPC service handler pub fn new(inner: T) -> Self { let inner = ServerStreaming::new(Inner(inner)); Unary { inner } } } impl Service for Unary where T: UnaryService, S: Stream, { type Request = Request; type Response = ::Response>; type Error = ::Error; type Future = ResponseFuture; fn poll_ready(&mut self) -> Poll<(), Self::Error> { Service::poll_ready(&mut self.inner) } fn call(&mut self, request: Self::Request) -> Self::Future { let inner = Service::call(&mut self.inner, request); ResponseFuture { inner } } } impl Clone for Unary where T: Clone, { fn clone(&self) -> Self { Unary { inner: self.inner.clone() } } } // ===== impl Inner ===== impl Service for Inner where T: UnaryService, { type Request = Request; type Response = Response>; type Error = ::Error; type Future = InnerFuture; fn poll_ready(&mut self) -> Poll<(), Self::Error> { self.0.poll_ready() } fn call(&mut self, request: Self::Request) -> Self::Future { let inner = self.0.call(request); InnerFuture(inner) } } // ===== impl ResponseFuture ====== impl Future for ResponseFuture where T: UnaryService, S: Stream, { type Item = Response>; type Error = ::Error; fn poll(&mut self) -> Poll { self.inner.poll() } } // ===== impl InnerFuture ====== impl Future for InnerFuture where T: Future, Error = ::Error> { type Item = Response>; type Error = ::Error; fn poll(&mut self) -> Poll { let response = try_ready!(self.0.poll()); Ok(Once::map(response).into()) } } // ===== impl Once ===== impl Once { /// Map a response to a response of a `Once` stream pub(super) fn map(response: Response) -> Response { // A bunch of junk to map the body type let http = response.into_http(); let (head, body) = http.into_parts(); // Wrap with `Once` let body = Once { inner: Some(body) }; let http = ::http::Response::from_parts(head, body); Response::from_http(http) } } impl Stream for Once { type Item = T; type Error = ::Error; fn poll(&mut self) -> Poll, Self::Error> { Ok(self.inner.take().into()) } }