xref: /tonic/examples/src/mock/mock.rs (revision 6cdb3d46)
1 use std::convert::TryFrom;
2 use tonic::{
3     transport::{Endpoint, Server, Uri},
4     Request, Response, Status,
5 };
6 use tower::service_fn;
7 
8 pub mod hello_world {
9     tonic::include_proto!("helloworld");
10 }
11 
12 use hello_world::{
13     greeter_client::GreeterClient,
14     greeter_server::{Greeter, GreeterServer},
15     HelloReply, HelloRequest,
16 };
17 
18 #[tokio::main]
19 async fn main() -> Result<(), Box<dyn std::error::Error>> {
20     let (client, server) = tokio::io::duplex(1024);
21 
22     let greeter = MyGreeter::default();
23 
24     tokio::spawn(async move {
25         Server::builder()
26             .add_service(GreeterServer::new(greeter))
27             .serve_with_incoming(futures::stream::iter(vec![Ok::<_, std::io::Error>(server)]))
28             .await
29     });
30 
31     // Move client to an option so we can _move_ the inner value
32     // on the first attempt to connect. All other attempts will fail.
33     let mut client = Some(client);
34     let channel = Endpoint::try_from("http://[::]:50051")?
35         .connect_with_connector(service_fn(move |_: Uri| {
36             let client = client.take();
37 
38             async move {
39                 if let Some(client) = client {
40                     Ok(client)
41                 } else {
42                     Err(std::io::Error::new(
43                         std::io::ErrorKind::Other,
44                         "Client already taken",
45                     ))
46                 }
47             }
48         }))
49         .await?;
50 
51     let mut client = GreeterClient::new(channel);
52 
53     let request = tonic::Request::new(HelloRequest {
54         name: "Tonic".into(),
55     });
56 
57     let response = client.say_hello(request).await?;
58 
59     println!("RESPONSE={:?}", response);
60 
61     Ok(())
62 }
63 
64 #[derive(Default)]
65 pub struct MyGreeter {}
66 
67 #[tonic::async_trait]
68 impl Greeter for MyGreeter {
69     async fn say_hello(
70         &self,
71         request: Request<HelloRequest>,
72     ) -> Result<Response<HelloReply>, Status> {
73         println!("Got a request: {:?}", request);
74 
75         let reply = hello_world::HelloReply {
76             message: format!("Hello {}!", request.into_inner().name),
77         };
78         Ok(Response::new(reply))
79     }
80 }
81