tower_grpc/generic/client/
mod.rs

1use crate::body::{Body, HttpBody};
2use crate::error::Error;
3
4use futures::{Future, Poll};
5use http::{Request, Response};
6use tower_service::Service;
7
8/// A specialization of tower_service::Service.
9///
10/// Existing tower_service::Service implementations with the correct form will
11/// automatically implement `GrpcService`.
12pub trait GrpcService<ReqBody> {
13    /// Response body type
14    type ResponseBody: Body + HttpBody;
15
16    /// Response future
17    type Future: Future<Item = Response<Self::ResponseBody>, Error = Self::Error>;
18
19    /// Error type
20    type Error: Into<Error>;
21
22    /// Poll that this service is ready.
23    fn poll_ready(&mut self) -> Poll<(), Self::Error>;
24
25    /// Call the service.
26    fn call(&mut self, request: Request<ReqBody>) -> Self::Future;
27
28    /// Helper when needing to pass this type to bounds needing `Service`.
29    fn into_service(self) -> IntoService<Self>
30    where
31        Self: Sized,
32    {
33        IntoService(self)
34    }
35
36    /// Helper when needing to pass this type to bounds needing `Service`.
37    fn as_service(&mut self) -> AsService<'_, Self>
38    where
39        Self: Sized,
40    {
41        AsService(self)
42    }
43}
44
45impl<T, ReqBody, ResBody> GrpcService<ReqBody> for T
46where
47    T: Service<Request<ReqBody>, Response = Response<ResBody>>,
48    T::Error: Into<Error>,
49    ResBody: Body + HttpBody,
50{
51    type ResponseBody = ResBody;
52    type Future = T::Future;
53    type Error = T::Error;
54
55    fn poll_ready(&mut self) -> Poll<(), Self::Error> {
56        Service::poll_ready(self)
57    }
58
59    fn call(&mut self, request: Request<ReqBody>) -> Self::Future {
60        Service::call(self, request)
61    }
62}
63
64/// Helper when needing to pass a `GrpcService` to bounds needing `Service`.
65#[derive(Debug)]
66pub struct AsService<'a, T>(&'a mut T);
67
68impl<'a, T, ReqBody> Service<Request<ReqBody>> for AsService<'a, T>
69where
70    T: GrpcService<ReqBody> + 'a,
71{
72    type Response = Response<T::ResponseBody>;
73    type Future = T::Future;
74    type Error = T::Error;
75
76    fn poll_ready(&mut self) -> Poll<(), Self::Error> {
77        GrpcService::poll_ready(self.0)
78    }
79
80    fn call(&mut self, request: Request<ReqBody>) -> Self::Future {
81        GrpcService::call(self.0, request)
82    }
83}
84
85/// Helper when needing to pass a `GrpcService` to bounds needing `Service`.
86#[derive(Debug)]
87pub struct IntoService<T>(pub(crate) T);
88
89impl<T, ReqBody> Service<Request<ReqBody>> for IntoService<T>
90where
91    T: GrpcService<ReqBody>,
92{
93    type Response = Response<T::ResponseBody>;
94    type Future = T::Future;
95    type Error = T::Error;
96
97    fn poll_ready(&mut self) -> Poll<(), Self::Error> {
98        GrpcService::poll_ready(&mut self.0)
99    }
100
101    fn call(&mut self, request: Request<ReqBody>) -> Self::Future {
102        GrpcService::call(&mut self.0, request)
103    }
104}