use tonic::{transport::Server, Code, Request, Response, Status}; use tonic_types::{BadRequest, Help, LocalizedMessage, StatusExt}; use hello_world::greeter_server::{Greeter, GreeterServer}; use hello_world::{HelloReply, HelloRequest}; pub mod hello_world { tonic::include_proto!("helloworld"); } #[derive(Default)] pub struct MyGreeter {} #[tonic::async_trait] impl Greeter for MyGreeter { async fn say_hello( &self, request: Request, ) -> Result, Status> { println!("Got a request from {:?}", request.remote_addr()); // Extract request data let name = request.into_inner().name; // Create empty BadRequest struct let mut bad_request = BadRequest::new(vec![]); // Add violations conditionally if name.is_empty() { bad_request.add_violation("name", "name cannot be empty"); } else if name.len() > 20 { bad_request.add_violation("name", "name is too long"); } if !bad_request.is_empty() { // Add additional error details if necessary let help = Help::with_link("description of link", "https://resource.example.local"); let localized_message = LocalizedMessage::new("en-US", "message for the user"); // Generate error status let status = Status::with_error_details_vec( Code::InvalidArgument, "request contains invalid arguments", vec![bad_request.into(), help.into(), localized_message.into()], ); return Err(status); } let reply = hello_world::HelloReply { message: format!("Hello {}!", name), }; Ok(Response::new(reply)) } } #[tokio::main] async fn main() -> Result<(), Box> { let addr = "[::1]:50051".parse().unwrap(); let greeter = MyGreeter::default(); println!("GreeterServer listening on {}", addr); Server::builder() .add_service(GreeterServer::new(greeter)) .serve(addr) .await?; Ok(()) }