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