1 use std::error::Error;
2 use std::time::Duration;
3
4 use rand::rngs::ThreadRng;
5 use rand::Rng;
6 use tokio::time;
7 use tonic::transport::Channel;
8 use tonic::Request;
9
10 use routeguide::route_guide_client::RouteGuideClient;
11 use routeguide::{Point, Rectangle, RouteNote};
12
13 pub mod routeguide {
14 tonic::include_proto!("routeguide");
15 }
16
print_features(client: &mut RouteGuideClient<Channel>) -> Result<(), Box<dyn Error>>17 async fn print_features(client: &mut RouteGuideClient<Channel>) -> Result<(), Box<dyn Error>> {
18 let rectangle = Rectangle {
19 lo: Some(Point {
20 latitude: 400_000_000,
21 longitude: -750_000_000,
22 }),
23 hi: Some(Point {
24 latitude: 420_000_000,
25 longitude: -730_000_000,
26 }),
27 };
28
29 let mut stream = client
30 .list_features(Request::new(rectangle))
31 .await?
32 .into_inner();
33
34 while let Some(feature) = stream.message().await? {
35 println!("FEATURE = {:?}", feature);
36 }
37
38 Ok(())
39 }
40
run_record_route(client: &mut RouteGuideClient<Channel>) -> Result<(), Box<dyn Error>>41 async fn run_record_route(client: &mut RouteGuideClient<Channel>) -> Result<(), Box<dyn Error>> {
42 let mut rng = rand::rng();
43 let point_count: i32 = rng.random_range(2..100);
44
45 let mut points = vec![];
46 for _ in 0..=point_count {
47 points.push(random_point(&mut rng))
48 }
49
50 println!("Traversing {} points", points.len());
51 let request = Request::new(tokio_stream::iter(points));
52
53 match client.record_route(request).await {
54 Ok(response) => println!("SUMMARY: {:?}", response.into_inner()),
55 Err(e) => println!("something went wrong: {:?}", e),
56 }
57
58 Ok(())
59 }
60
run_route_chat(client: &mut RouteGuideClient<Channel>) -> Result<(), Box<dyn Error>>61 async fn run_route_chat(client: &mut RouteGuideClient<Channel>) -> Result<(), Box<dyn Error>> {
62 let start = time::Instant::now();
63
64 let outbound = async_stream::stream! {
65 let mut interval = time::interval(Duration::from_secs(1));
66
67 loop {
68 let time = interval.tick().await;
69 let elapsed = time.duration_since(start);
70 let note = RouteNote {
71 location: Some(Point {
72 latitude: 409146138 + elapsed.as_secs() as i32,
73 longitude: -746188906,
74 }),
75 message: format!("at {:?}", elapsed),
76 };
77
78 yield note;
79 }
80 };
81
82 let response = client.route_chat(Request::new(outbound)).await?;
83 let mut inbound = response.into_inner();
84
85 while let Some(note) = inbound.message().await? {
86 println!("NOTE = {:?}", note);
87 }
88
89 Ok(())
90 }
91
92 #[tokio::main]
main() -> Result<(), Box<dyn std::error::Error>>93 async fn main() -> Result<(), Box<dyn std::error::Error>> {
94 let mut client = RouteGuideClient::connect("http://[::1]:10000").await?;
95
96 println!("*** SIMPLE RPC ***");
97 let response = client
98 .get_feature(Request::new(Point {
99 latitude: 409_146_138,
100 longitude: -746_188_906,
101 }))
102 .await?;
103 println!("RESPONSE = {:?}", response);
104
105 println!("\n*** SERVER STREAMING ***");
106 print_features(&mut client).await?;
107
108 println!("\n*** CLIENT STREAMING ***");
109 run_record_route(&mut client).await?;
110
111 println!("\n*** BIDIRECTIONAL STREAMING ***");
112 run_route_chat(&mut client).await?;
113
114 Ok(())
115 }
116
random_point(rng: &mut ThreadRng) -> Point117 fn random_point(rng: &mut ThreadRng) -> Point {
118 let latitude = (rng.random_range(0..180) - 90) * 10_000_000;
119 let longitude = (rng.random_range(0..360) - 180) * 10_000_000;
120 Point {
121 latitude,
122 longitude,
123 }
124 }
125