xref: /tonic/examples/src/tower/client.rs (revision 6c898a23)
1 use hello_world::greeter_client::GreeterClient;
2 use hello_world::HelloRequest;
3 use service::AuthSvc;
4 
5 use tonic::transport::Channel;
6 
7 pub mod hello_world {
8     tonic::include_proto!("helloworld");
9 }
10 
11 #[tokio::main]
12 async fn main() -> Result<(), Box<dyn std::error::Error>> {
13     let channel = Channel::from_static("http://[::1]:50051").connect().await?;
14     let auth = AuthSvc::new(channel);
15 
16     let mut client = GreeterClient::new(auth);
17 
18     let request = tonic::Request::new(HelloRequest {
19         name: "Tonic".into(),
20     });
21 
22     let response = client.say_hello(request).await?;
23 
24     println!("RESPONSE={:?}", response);
25 
26     Ok(())
27 }
28 
29 mod service {
30     use http::{Request, Response};
31     use std::future::Future;
32     use std::pin::Pin;
33     use std::task::{Context, Poll};
34     use tonic::body::BoxBody;
35     use tonic::transport::Body;
36     use tonic::transport::Channel;
37     use tower::Service;
38 
39     pub struct AuthSvc {
40         inner: Channel,
41     }
42 
43     impl AuthSvc {
44         pub fn new(inner: Channel) -> Self {
45             AuthSvc { inner }
46         }
47     }
48 
49     impl Service<Request<BoxBody>> for AuthSvc {
50         type Response = Response<Body>;
51         type Error = Box<dyn std::error::Error + Send + Sync>;
52         type Future = Pin<Box<dyn Future<Output = Result<Self::Response, Self::Error>> + Send>>;
53 
54         fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
55             self.inner.poll_ready(cx).map_err(Into::into)
56         }
57 
58         fn call(&mut self, req: Request<BoxBody>) -> Self::Future {
59             let mut channel = self.inner.clone();
60 
61             Box::pin(async move {
62                 // Do extra async work here...
63 
64                 channel.call(req).await.map_err(Into::into)
65             })
66         }
67     }
68 }
69