extern crate futures;
extern crate grpcio;
extern crate grpcio_proto;
#[macro_use]
extern crate log;
extern crate rand;
#[macro_use]
extern crate serde_derive;
extern crate serde_json;
mod util;
#[path = "../log_util.rs"]
mod log_util;
use std::sync::Arc;
use std::time::Duration;
use std::thread;
use futures::{future, Future, Sink, Stream};
use grpcio::*;
use grpcio_proto::example::route_guide::{Point, Rectangle, RouteNote};
use grpcio_proto::example::route_guide_grpc::RouteGuideClient;
use rand::Rng;
fn new_point(lat: i32, lon: i32) -> Point {
let mut point = Point::new();
point.set_latitude(lat);
point.set_longitude(lon);
point
}
fn new_rect(lat1: i32, lon1: i32, lat2: i32, lon2: i32) -> Rectangle {
let mut rect = Rectangle::new();
rect.set_lo(new_point(lat1, lon1));
rect.set_hi(new_point(lat2, lon2));
rect
}
fn new_note(lat: i32, lon: i32, msg: &str) -> RouteNote {
let mut note = RouteNote::new();
note.set_location(new_point(lat, lon));
note.set_message(msg.to_owned());
note
}
fn get_feature(client: &RouteGuideClient, point: &Point) {
let get_feature = client.get_feature_async(point).unwrap();
match get_feature.wait() {
Err(e) => panic!("RPC failed: {:?}", e),
Ok(f) => {
if !f.has_location() {
warn!("Server returns incomplete feature.");
return;
}
if f.get_name().is_empty() {
warn!("Found no feature at {}", util::format_point(point));
return;
}
info!(
"Found feature called {} at {}",
f.get_name(),
util::format_point(point)
);
}
}
}
fn list_features(client: &RouteGuideClient) {
let rect = new_rect(400_000_000, -750_000_000, 420_000_000, -730_000_000);
info!("Looking for features between 40, -75 and 42, -73");
let mut list_features = client.list_features(&rect).unwrap();
loop {
let f = list_features.into_future();
match f.wait() {
Ok((Some(feature), s)) => {
list_features = s;
let loc = feature.get_location();
info!(
"Found feature {} at {}",
feature.get_name(),
util::format_point(loc)
);
}
Ok((None, _)) => break,
Err((e, _)) => panic!("List features failed: {:?}", e),
}
}
info!("List feature rpc succeeded.");
}
fn record_route(client: &RouteGuideClient) {
let features = util::load_db();
let mut rng = rand::thread_rng();
let (mut sink, receiver) = client.record_route().unwrap();
for _ in 0..10 {
let f = rng.choose(&features).unwrap();
let point = f.get_location();
info!("Visiting {}", util::format_point(point));
sink = sink.send((point.to_owned(), WriteFlags::default()))
.wait()
.unwrap();
thread::sleep(Duration::from_millis(rng.gen_range(500, 1500)));
}
future::poll_fn(|| sink.close()).wait().unwrap();
let sumary = receiver.wait().unwrap();
info!("Finished trip with {} points", sumary.get_point_count());
info!("Passed {} features", sumary.get_feature_count());
info!("Travelled {} meters", sumary.get_distance());
info!("It took {} seconds", sumary.get_elapsed_time());
}
fn route_chat(client: &RouteGuideClient) {
let (mut sink, mut receiver) = client.route_chat().unwrap();
let h = thread::spawn(move || {
let notes = vec![
("First message", 0, 0),
("Second message", 0, 1),
("Third message", 1, 0),
("Fourth message", 0, 0),
];
for (msg, lat, lon) in notes {
let note = new_note(lat, lon, msg);
info!("Sending message {} at {}, {}", msg, lat, lon);
sink = sink.send((note, WriteFlags::default())).wait().unwrap();
}
future::poll_fn(|| sink.close()).wait().unwrap();
});
loop {
match receiver.into_future().wait() {
Ok((Some(note), r)) => {
let location = note.get_location();
info!(
"Got message {} at {}, {}",
note.get_message(),
location.get_latitude(),
location.get_longitude()
);
receiver = r;
}
Ok((None, _)) => break,
Err((e, _)) => panic!("RouteChat RPC failed: {:?}", e),
}
}
h.join().unwrap();
}
fn main() {
let _guard = log_util::init_log(None);
let env = Arc::new(Environment::new(2));
let channel = ChannelBuilder::new(env).connect("127.0.0.1:50051");
let client = RouteGuideClient::new(channel);
info!("-------------- GetFeature --------------");
get_feature(&client, &new_point(409_146_138, -746_188_906));
get_feature(&client, &new_point(0, 0));
info!("-------------- ListFeatures --------------");
list_features(&client);
info!("-------------- RecordRoute --------------");
record_route(&client);
info!("-------------- RouteChat --------------");
route_chat(&client);
}