From 0847b67c4eb66a814c8c447a57fade2552e64a85 Mon Sep 17 00:00:00 2001 From: Lucio Franco Date: Wed, 11 Dec 2019 16:22:03 -0500 Subject: [PATCH] fix(build): Allow creating multiple services in the same package (#173) BREAKING CHANGE: Build will now generate each service client and server into their own modules. --- tests/included_service/src/lib.rs | 2 +- tonic-build/src/client.rs | 60 +++++++------ tonic-build/src/lib.rs | 16 +--- tonic-build/src/server.rs | 89 +++++++++++--------- tonic-examples/src/authentication/client.rs | 2 +- tonic-examples/src/authentication/server.rs | 4 +- tonic-examples/src/gcp/client.rs | 2 +- tonic-examples/src/helloworld/client.rs | 2 +- tonic-examples/src/helloworld/server.rs | 2 +- tonic-examples/src/load_balance/client.rs | 2 +- tonic-examples/src/load_balance/server.rs | 4 +- tonic-examples/src/multiplex/client.rs | 4 +- tonic-examples/src/multiplex/server.rs | 4 +- tonic-examples/src/routeguide/client.rs | 2 +- tonic-examples/src/routeguide/server.rs | 6 +- tonic-examples/src/tls/client.rs | 2 +- tonic-examples/src/tls/server.rs | 4 +- tonic-examples/src/tls_client_auth/client.rs | 2 +- tonic-examples/src/tls_client_auth/server.rs | 4 +- tonic-interop/src/client.rs | 5 +- tonic-interop/src/server.rs | 7 +- 21 files changed, 115 insertions(+), 110 deletions(-) diff --git a/tests/included_service/src/lib.rs b/tests/included_service/src/lib.rs index d8e6f10..be30849 100644 --- a/tests/included_service/src/lib.rs +++ b/tests/included_service/src/lib.rs @@ -5,4 +5,4 @@ pub mod pb { // Ensure that an RPC service, defined before including a file that defines // another service in a different protocol buffer package, is not incorrectly // cleared from the context of its package. -type _Test = dyn pb::server::TopService; +type _Test = dyn pb::topservice_server::TopService; diff --git a/tonic-build/src/client.rs b/tonic-build/src/client.rs index e926fe0..20b5f7e 100644 --- a/tonic-build/src/client.rs +++ b/tonic-build/src/client.rs @@ -5,44 +5,50 @@ use quote::{format_ident, quote}; pub(crate) fn generate(service: &Service, proto: &str) -> TokenStream { let service_ident = quote::format_ident!("{}Client", service.name); + let client_mod = quote::format_ident!("{}_client", service.name.to_ascii_lowercase()); let methods = generate_methods(service, proto); let connect = generate_connect(&service_ident); let service_doc = generate_doc_comments(&service.comments.leading); quote! { - #service_doc - pub struct #service_ident { - inner: tonic::client::Grpc, - } + /// Generated server implementations. + pub mod #client_mod { + #![allow(unused_variables, dead_code, missing_docs)] + use tonic::codegen::*; - #connect - - impl #service_ident - where T: tonic::client::GrpcService, - T::ResponseBody: Body + HttpBody + Send + 'static, - T::Error: Into, - ::Error: Into + Send, - { - pub fn new(inner: T) -> Self { - let inner = tonic::client::Grpc::new(inner); - Self { inner } + #service_doc + pub struct #service_ident { + inner: tonic::client::Grpc, } - /// Check if the service is ready. - pub async fn ready(&mut self) -> Result<(), tonic::Status> { - self.inner.ready().await.map_err(|e| { - tonic::Status::new(tonic::Code::Unknown, format!("Service was not ready: {}", e.into())) - }) + #connect + + impl #service_ident + where T: tonic::client::GrpcService, + T::ResponseBody: Body + HttpBody + Send + 'static, + T::Error: Into, + ::Error: Into + Send, { + pub fn new(inner: T) -> Self { + let inner = tonic::client::Grpc::new(inner); + Self { inner } + } + + /// Check if the service is ready. + pub async fn ready(&mut self) -> Result<(), tonic::Status> { + self.inner.ready().await.map_err(|e| { + tonic::Status::new(tonic::Code::Unknown, format!("Service was not ready: {}", e.into())) + }) + } + + #methods } - #methods - } - - impl Clone for #service_ident { - fn clone(&self) -> Self { - Self { - inner: self.inner.clone(), + impl Clone for #service_ident { + fn clone(&self) -> Self { + Self { + inner: self.inner.clone(), + } } } } diff --git a/tonic-build/src/lib.rs b/tonic-build/src/lib.rs index 2494b17..aca9a1c 100644 --- a/tonic-build/src/lib.rs +++ b/tonic-build/src/lib.rs @@ -251,13 +251,7 @@ impl prost_build::ServiceGenerator for ServiceGenerator { let clients = &self.clients; let client_service = quote::quote! { - /// Generated client implementations. - pub mod client { - #![allow(unused_variables, dead_code, missing_docs)] - use tonic::codegen::*; - - #clients - } + #clients }; let code = format!("{}", client_service); @@ -270,13 +264,7 @@ impl prost_build::ServiceGenerator for ServiceGenerator { let servers = &self.servers; let server_service = quote::quote! { - /// Generated server implementations. - pub mod server { - #![allow(unused_variables, dead_code, missing_docs)] - use tonic::codegen::*; - - #servers - } + #servers }; let code = format!("{}", server_service); diff --git a/tonic-build/src/server.rs b/tonic-build/src/server.rs index 9442eb2..fab3fe8 100644 --- a/tonic-build/src/server.rs +++ b/tonic-build/src/server.rs @@ -9,6 +9,7 @@ pub(crate) fn generate(service: &Service, proto_path: &str) -> TokenStream { let server_service = quote::format_ident!("{}Server", service.name); let server_trait = quote::format_ident!("{}", service.name); + let server_mod = quote::format_ident!("{}_server", service.name.to_ascii_lowercase()); let generated_trait = generate_trait(service, proto_path, server_trait.clone()); let service_doc = generate_doc_comments(&service.comments.leading); @@ -17,56 +18,62 @@ pub(crate) fn generate(service: &Service, proto_path: &str) -> TokenStream { let transport = generate_transport(&server_service, &server_trait, &path); quote! { - #generated_trait + /// Generated server implementations. + pub mod #server_mod { + #![allow(unused_variables, dead_code, missing_docs)] + use tonic::codegen::*; - #service_doc - #[derive(Debug)] - #[doc(hidden)] - pub struct #server_service { - inner: Arc, - } + #generated_trait - impl #server_service { - pub fn new(inner: T) -> Self { - let inner = Arc::new(inner); - Self { inner } - } - } - - impl Service> for #server_service { - type Response = http::Response; - type Error = Never; - type Future = BoxFuture; - - fn poll_ready(&mut self, _cx: &mut Context<'_>) -> Poll> { - Poll::Ready(Ok(())) + #service_doc + #[derive(Debug)] + #[doc(hidden)] + pub struct #server_service { + inner: Arc, } - fn call(&mut self, req: http::Request) -> Self::Future { - let inner = self.inner.clone(); - - match req.uri().path() { - #methods - - _ => Box::pin(async move { - Ok(http::Response::builder() - .status(200) - .header("grpc-status", "12") - .body(tonic::body::BoxBody::empty()) - .unwrap()) - }), + impl #server_service { + pub fn new(inner: T) -> Self { + let inner = Arc::new(inner); + Self { inner } } } - } - impl Clone for #server_service { - fn clone(&self) -> Self { - let inner = self.inner.clone(); - Self { inner } + impl Service> for #server_service { + type Response = http::Response; + type Error = Never; + type Future = BoxFuture; + + fn poll_ready(&mut self, _cx: &mut Context<'_>) -> Poll> { + Poll::Ready(Ok(())) + } + + fn call(&mut self, req: http::Request) -> Self::Future { + let inner = self.inner.clone(); + + match req.uri().path() { + #methods + + _ => Box::pin(async move { + Ok(http::Response::builder() + .status(200) + .header("grpc-status", "12") + .body(tonic::body::BoxBody::empty()) + .unwrap()) + }), + } + } } - } - #transport + impl Clone for #server_service { + fn clone(&self) -> Self { + let inner = self.inner.clone(); + Self { inner } + } + } + + #transport + } } } diff --git a/tonic-examples/src/authentication/client.rs b/tonic-examples/src/authentication/client.rs index b514773..b97b02b 100644 --- a/tonic-examples/src/authentication/client.rs +++ b/tonic-examples/src/authentication/client.rs @@ -3,7 +3,7 @@ pub mod pb { } use http::header::HeaderValue; -use pb::{client::EchoClient, EchoRequest}; +use pb::{echo_client::EchoClient, EchoRequest}; use tonic::transport::Channel; #[tokio::main] diff --git a/tonic-examples/src/authentication/server.rs b/tonic-examples/src/authentication/server.rs index 006f445..94b0dba 100644 --- a/tonic-examples/src/authentication/server.rs +++ b/tonic-examples/src/authentication/server.rs @@ -15,7 +15,7 @@ type ResponseStream = Pin> + pub struct EchoServer; #[tonic::async_trait] -impl pb::server::Echo for EchoServer { +impl pb::echo_server::Echo for EchoServer { async fn unary_echo(&self, request: Request) -> EchoResult { let message = request.into_inner().message; Ok(Response::new(EchoResponse { message })) @@ -79,7 +79,7 @@ async fn main() -> Result<(), Box> { } } }) - .add_service(pb::server::EchoServer::new(server)) + .add_service(pb::echo_server::EchoServer::new(server)) .serve(addr) .await?; diff --git a/tonic-examples/src/gcp/client.rs b/tonic-examples/src/gcp/client.rs index c698ba8..9138de5 100644 --- a/tonic-examples/src/gcp/client.rs +++ b/tonic-examples/src/gcp/client.rs @@ -2,7 +2,7 @@ pub mod api { tonic::include_proto!("google.pubsub.v1"); } -use api::{client::PublisherClient, ListTopicsRequest}; +use api::{publisher_client::PublisherClient, ListTopicsRequest}; use http::header::HeaderValue; use tonic::{ transport::{Certificate, Channel, ClientTlsConfig}, diff --git a/tonic-examples/src/helloworld/client.rs b/tonic-examples/src/helloworld/client.rs index 227be6b..486e1d8 100644 --- a/tonic-examples/src/helloworld/client.rs +++ b/tonic-examples/src/helloworld/client.rs @@ -2,7 +2,7 @@ pub mod hello_world { tonic::include_proto!("helloworld"); } -use hello_world::{client::GreeterClient, HelloRequest}; +use hello_world::{greeter_client::GreeterClient, HelloRequest}; #[tokio::main] async fn main() -> Result<(), Box> { diff --git a/tonic-examples/src/helloworld/server.rs b/tonic-examples/src/helloworld/server.rs index 211c4e6..23a3454 100644 --- a/tonic-examples/src/helloworld/server.rs +++ b/tonic-examples/src/helloworld/server.rs @@ -5,7 +5,7 @@ pub mod hello_world { } use hello_world::{ - server::{Greeter, GreeterServer}, + greeter_server::{Greeter, GreeterServer}, HelloReply, HelloRequest, }; diff --git a/tonic-examples/src/load_balance/client.rs b/tonic-examples/src/load_balance/client.rs index 904605a..169546c 100644 --- a/tonic-examples/src/load_balance/client.rs +++ b/tonic-examples/src/load_balance/client.rs @@ -2,7 +2,7 @@ pub mod pb { tonic::include_proto!("grpc.examples.echo"); } -use pb::{client::EchoClient, EchoRequest}; +use pb::{echo_client::EchoClient, EchoRequest}; use tonic::transport::Channel; #[tokio::main] diff --git a/tonic-examples/src/load_balance/server.rs b/tonic-examples/src/load_balance/server.rs index aa95f91..8623d8f 100644 --- a/tonic-examples/src/load_balance/server.rs +++ b/tonic-examples/src/load_balance/server.rs @@ -19,7 +19,7 @@ pub struct EchoServer { } #[tonic::async_trait] -impl pb::server::Echo for EchoServer { +impl pb::echo_server::Echo for EchoServer { async fn unary_echo(&self, request: Request) -> EchoResult { let message = format!("{} (from {})", request.into_inner().message, self.addr); @@ -64,7 +64,7 @@ async fn main() -> Result<(), Box> { let server = EchoServer { addr }; let serve = Server::builder() - .add_service(pb::server::EchoServer::new(server)) + .add_service(pb::echo_server::EchoServer::new(server)) .serve(addr); tokio::spawn(async move { diff --git a/tonic-examples/src/multiplex/client.rs b/tonic-examples/src/multiplex/client.rs index 30f72a3..b799036 100644 --- a/tonic-examples/src/multiplex/client.rs +++ b/tonic-examples/src/multiplex/client.rs @@ -6,8 +6,8 @@ pub mod echo { tonic::include_proto!("grpc.examples.echo"); } -use echo::{client::EchoClient, EchoRequest}; -use hello_world::{client::GreeterClient, HelloRequest}; +use echo::{echo_client::EchoClient, EchoRequest}; +use hello_world::{greeter_client::GreeterClient, HelloRequest}; use tonic::transport::Endpoint; #[tokio::main] diff --git a/tonic-examples/src/multiplex/server.rs b/tonic-examples/src/multiplex/server.rs index 526b887..c10575d 100644 --- a/tonic-examples/src/multiplex/server.rs +++ b/tonic-examples/src/multiplex/server.rs @@ -11,12 +11,12 @@ pub mod echo { } use hello_world::{ - server::{Greeter, GreeterServer}, + greeter_server::{Greeter, GreeterServer}, HelloReply, HelloRequest, }; use echo::{ - server::{Echo, EchoServer}, + echo_server::{Echo, EchoServer}, EchoRequest, EchoResponse, }; diff --git a/tonic-examples/src/routeguide/client.rs b/tonic-examples/src/routeguide/client.rs index e428712..b549e27 100644 --- a/tonic-examples/src/routeguide/client.rs +++ b/tonic-examples/src/routeguide/client.rs @@ -12,7 +12,7 @@ pub mod route_guide { tonic::include_proto!("routeguide"); } -use route_guide::client::RouteGuideClient; +use route_guide::routeguide_client::RouteGuideClient; async fn print_features(client: &mut RouteGuideClient) -> Result<(), Box> { let rectangle = Rectangle { diff --git a/tonic-examples/src/routeguide/server.rs b/tonic-examples/src/routeguide/server.rs index 40d1022..f766957 100644 --- a/tonic-examples/src/routeguide/server.rs +++ b/tonic-examples/src/routeguide/server.rs @@ -14,7 +14,7 @@ pub mod routeguide { tonic::include_proto!("routeguide"); } -use routeguide::{server, Feature, Point, Rectangle, RouteNote, RouteSummary}; +use routeguide::{routeguide_server, Feature, Point, Rectangle, RouteNote, RouteSummary}; #[derive(Debug)] pub struct RouteGuide { @@ -22,7 +22,7 @@ pub struct RouteGuide { } #[tonic::async_trait] -impl server::RouteGuide for RouteGuide { +impl routeguide_server::RouteGuide for RouteGuide { async fn get_feature(&self, request: Request) -> Result, Status> { println!("GetFeature = {:?}", request); @@ -154,7 +154,7 @@ async fn main() -> Result<(), Box> { features: Arc::new(data::load()), }; - let svc = server::RouteGuideServer::new(route_guide); + let svc = routeguide_server::RouteGuideServer::new(route_guide); Server::builder().add_service(svc).serve(addr).await?; diff --git a/tonic-examples/src/tls/client.rs b/tonic-examples/src/tls/client.rs index f7060e7..b40929e 100644 --- a/tonic-examples/src/tls/client.rs +++ b/tonic-examples/src/tls/client.rs @@ -2,7 +2,7 @@ pub mod pb { tonic::include_proto!("/grpc.examples.echo"); } -use pb::{client::EchoClient, EchoRequest}; +use pb::{echo_client::EchoClient, EchoRequest}; use tonic::transport::{Certificate, Channel, ClientTlsConfig}; #[tokio::main] diff --git a/tonic-examples/src/tls/server.rs b/tonic-examples/src/tls/server.rs index 2aceca6..1fb01e4 100644 --- a/tonic-examples/src/tls/server.rs +++ b/tonic-examples/src/tls/server.rs @@ -17,7 +17,7 @@ type ResponseStream = Pin> + pub struct EchoServer; #[tonic::async_trait] -impl pb::server::Echo for EchoServer { +impl pb::echo_server::Echo for EchoServer { async fn unary_echo(&self, request: Request) -> EchoResult { let message = request.into_inner().message; Ok(Response::new(EchoResponse { message })) @@ -61,7 +61,7 @@ async fn main() -> Result<(), Box> { Server::builder() .tls_config(ServerTlsConfig::with_rustls().identity(identity)) - .add_service(pb::server::EchoServer::new(server)) + .add_service(pb::echo_server::EchoServer::new(server)) .serve(addr) .await?; diff --git a/tonic-examples/src/tls_client_auth/client.rs b/tonic-examples/src/tls_client_auth/client.rs index a77212a..44806ed 100644 --- a/tonic-examples/src/tls_client_auth/client.rs +++ b/tonic-examples/src/tls_client_auth/client.rs @@ -2,7 +2,7 @@ pub mod pb { tonic::include_proto!("grpc.examples.echo"); } -use pb::{client::EchoClient, EchoRequest}; +use pb::{echo_client::EchoClient, EchoRequest}; use tonic::transport::{Certificate, Channel, ClientTlsConfig, Identity}; #[tokio::main] diff --git a/tonic-examples/src/tls_client_auth/server.rs b/tonic-examples/src/tls_client_auth/server.rs index f987c74..5bff8c8 100644 --- a/tonic-examples/src/tls_client_auth/server.rs +++ b/tonic-examples/src/tls_client_auth/server.rs @@ -15,7 +15,7 @@ type ResponseStream = Pin> + pub struct EchoServer; #[tonic::async_trait] -impl pb::server::Echo for EchoServer { +impl pb::echo_server::Echo for EchoServer { async fn unary_echo(&self, request: Request) -> EchoResult { let message = request.into_inner().message; Ok(Response::new(EchoResponse { message })) @@ -43,7 +43,7 @@ async fn main() -> Result<(), Box> { Server::builder() .tls_config(tls) - .add_service(pb::server::EchoServer::new(server)) + .add_service(pb::echo_server::EchoServer::new(server)) .serve(addr) .await?; diff --git a/tonic-interop/src/client.rs b/tonic-interop/src/client.rs index 351c2c3..b75da6e 100644 --- a/tonic-interop/src/client.rs +++ b/tonic-interop/src/client.rs @@ -1,4 +1,7 @@ -use crate::{pb::client::*, pb::*, test_assert, TestAssertion}; +use crate::{ + pb::testservice_client::*, pb::unimplementedservice_client::*, pb::*, test_assert, + TestAssertion, +}; use futures_util::{future, stream, StreamExt}; use tokio::sync::mpsc; use tonic::transport::Channel; diff --git a/tonic-interop/src/server.rs b/tonic-interop/src/server.rs index aa6c425..2b613d1 100644 --- a/tonic-interop/src/server.rs +++ b/tonic-interop/src/server.rs @@ -5,7 +5,8 @@ use std::pin::Pin; use std::time::Duration; use tonic::{Code, Request, Response, Status}; -pub use pb::server::{TestServiceServer, UnimplementedServiceServer}; +pub use pb::testservice_server::TestServiceServer; +pub use pb::unimplementedservice_server::UnimplementedServiceServer; #[derive(Default, Clone)] pub struct TestService; @@ -17,7 +18,7 @@ type Stream = Pin< >; #[tonic::async_trait] -impl pb::server::TestService for TestService { +impl pb::testservice_server::TestService for TestService { async fn empty_call(&self, _request: Request) -> Result { Ok(Response::new(Empty {})) } @@ -153,7 +154,7 @@ impl pb::server::TestService for TestService { pub struct UnimplementedService; #[tonic::async_trait] -impl pb::server::UnimplementedService for UnimplementedService { +impl pb::unimplementedservice_server::UnimplementedService for UnimplementedService { async fn unimplemented_call(&self, _req: Request) -> Result { Err(Status::unimplemented("")) }