Skip to content

Commit 0847b67

Browse files
authored
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.
1 parent 393a57e commit 0847b67

File tree

21 files changed

+113
-108
lines changed

21 files changed

+113
-108
lines changed

tests/included_service/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,4 @@ pub mod pb {
55
// Ensure that an RPC service, defined before including a file that defines
66
// another service in a different protocol buffer package, is not incorrectly
77
// cleared from the context of its package.
8-
type _Test = dyn pb::server::TopService;
8+
type _Test = dyn pb::topservice_server::TopService;

tonic-build/src/client.rs

Lines changed: 34 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -5,44 +5,50 @@ use quote::{format_ident, quote};
55

66
pub(crate) fn generate(service: &Service, proto: &str) -> TokenStream {
77
let service_ident = quote::format_ident!("{}Client", service.name);
8+
let client_mod = quote::format_ident!("{}_client", service.name.to_ascii_lowercase());
89
let methods = generate_methods(service, proto);
910

1011
let connect = generate_connect(&service_ident);
1112
let service_doc = generate_doc_comments(&service.comments.leading);
1213

1314
quote! {
14-
#service_doc
15-
pub struct #service_ident<T> {
16-
inner: tonic::client::Grpc<T>,
17-
}
18-
19-
#connect
20-
21-
impl<T> #service_ident<T>
22-
where T: tonic::client::GrpcService<tonic::body::BoxBody>,
23-
T::ResponseBody: Body + HttpBody + Send + 'static,
24-
T::Error: Into<StdError>,
25-
<T::ResponseBody as HttpBody>::Error: Into<StdError> + Send,
26-
{
27-
pub fn new(inner: T) -> Self {
28-
let inner = tonic::client::Grpc::new(inner);
29-
Self { inner }
15+
/// Generated server implementations.
16+
pub mod #client_mod {
17+
#![allow(unused_variables, dead_code, missing_docs)]
18+
use tonic::codegen::*;
19+
20+
#service_doc
21+
pub struct #service_ident<T> {
22+
inner: tonic::client::Grpc<T>,
3023
}
3124

32-
/// Check if the service is ready.
33-
pub async fn ready(&mut self) -> Result<(), tonic::Status> {
34-
self.inner.ready().await.map_err(|e| {
35-
tonic::Status::new(tonic::Code::Unknown, format!("Service was not ready: {}", e.into()))
36-
})
37-
}
25+
#connect
3826

39-
#methods
40-
}
27+
impl<T> #service_ident<T>
28+
where T: tonic::client::GrpcService<tonic::body::BoxBody>,
29+
T::ResponseBody: Body + HttpBody + Send + 'static,
30+
T::Error: Into<StdError>,
31+
<T::ResponseBody as HttpBody>::Error: Into<StdError> + Send, {
32+
pub fn new(inner: T) -> Self {
33+
let inner = tonic::client::Grpc::new(inner);
34+
Self { inner }
35+
}
36+
37+
/// Check if the service is ready.
38+
pub async fn ready(&mut self) -> Result<(), tonic::Status> {
39+
self.inner.ready().await.map_err(|e| {
40+
tonic::Status::new(tonic::Code::Unknown, format!("Service was not ready: {}", e.into()))
41+
})
42+
}
43+
44+
#methods
45+
}
4146

42-
impl<T: Clone> Clone for #service_ident<T> {
43-
fn clone(&self) -> Self {
44-
Self {
45-
inner: self.inner.clone(),
47+
impl<T: Clone> Clone for #service_ident<T> {
48+
fn clone(&self) -> Self {
49+
Self {
50+
inner: self.inner.clone(),
51+
}
4652
}
4753
}
4854
}

tonic-build/src/lib.rs

Lines changed: 2 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -251,13 +251,7 @@ impl prost_build::ServiceGenerator for ServiceGenerator {
251251
let clients = &self.clients;
252252

253253
let client_service = quote::quote! {
254-
/// Generated client implementations.
255-
pub mod client {
256-
#![allow(unused_variables, dead_code, missing_docs)]
257-
use tonic::codegen::*;
258-
259-
#clients
260-
}
254+
#clients
261255
};
262256

263257
let code = format!("{}", client_service);
@@ -270,13 +264,7 @@ impl prost_build::ServiceGenerator for ServiceGenerator {
270264
let servers = &self.servers;
271265

272266
let server_service = quote::quote! {
273-
/// Generated server implementations.
274-
pub mod server {
275-
#![allow(unused_variables, dead_code, missing_docs)]
276-
use tonic::codegen::*;
277-
278-
#servers
279-
}
267+
#servers
280268
};
281269

282270
let code = format!("{}", server_service);

tonic-build/src/server.rs

Lines changed: 45 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ pub(crate) fn generate(service: &Service, proto_path: &str) -> TokenStream {
99

1010
let server_service = quote::format_ident!("{}Server", service.name);
1111
let server_trait = quote::format_ident!("{}", service.name);
12+
let server_mod = quote::format_ident!("{}_server", service.name.to_ascii_lowercase());
1213
let generated_trait = generate_trait(service, proto_path, server_trait.clone());
1314
let service_doc = generate_doc_comments(&service.comments.leading);
1415

@@ -17,56 +18,62 @@ pub(crate) fn generate(service: &Service, proto_path: &str) -> TokenStream {
1718
let transport = generate_transport(&server_service, &server_trait, &path);
1819

1920
quote! {
20-
#generated_trait
21-
22-
#service_doc
23-
#[derive(Debug)]
24-
#[doc(hidden)]
25-
pub struct #server_service<T: #server_trait> {
26-
inner: Arc<T>,
27-
}
21+
/// Generated server implementations.
22+
pub mod #server_mod {
23+
#![allow(unused_variables, dead_code, missing_docs)]
24+
use tonic::codegen::*;
25+
26+
#generated_trait
27+
28+
#service_doc
29+
#[derive(Debug)]
30+
#[doc(hidden)]
31+
pub struct #server_service<T: #server_trait> {
32+
inner: Arc<T>,
33+
}
2834

29-
impl<T: #server_trait> #server_service<T> {
30-
pub fn new(inner: T) -> Self {
31-
let inner = Arc::new(inner);
32-
Self { inner }
35+
impl<T: #server_trait> #server_service<T> {
36+
pub fn new(inner: T) -> Self {
37+
let inner = Arc::new(inner);
38+
Self { inner }
39+
}
3340
}
34-
}
3541

36-
impl<T: #server_trait> Service<http::Request<HyperBody>> for #server_service<T> {
37-
type Response = http::Response<tonic::body::BoxBody>;
38-
type Error = Never;
39-
type Future = BoxFuture<Self::Response, Self::Error>;
42+
impl<T: #server_trait> Service<http::Request<HyperBody>> for #server_service<T> {
43+
type Response = http::Response<tonic::body::BoxBody>;
44+
type Error = Never;
45+
type Future = BoxFuture<Self::Response, Self::Error>;
4046

41-
fn poll_ready(&mut self, _cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
42-
Poll::Ready(Ok(()))
43-
}
47+
fn poll_ready(&mut self, _cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
48+
Poll::Ready(Ok(()))
49+
}
4450

45-
fn call(&mut self, req: http::Request<HyperBody>) -> Self::Future {
46-
let inner = self.inner.clone();
51+
fn call(&mut self, req: http::Request<HyperBody>) -> Self::Future {
52+
let inner = self.inner.clone();
4753

48-
match req.uri().path() {
49-
#methods
54+
match req.uri().path() {
55+
#methods
5056

51-
_ => Box::pin(async move {
52-
Ok(http::Response::builder()
53-
.status(200)
54-
.header("grpc-status", "12")
55-
.body(tonic::body::BoxBody::empty())
56-
.unwrap())
57-
}),
57+
_ => Box::pin(async move {
58+
Ok(http::Response::builder()
59+
.status(200)
60+
.header("grpc-status", "12")
61+
.body(tonic::body::BoxBody::empty())
62+
.unwrap())
63+
}),
64+
}
5865
}
5966
}
60-
}
6167

62-
impl<T: #server_trait> Clone for #server_service<T> {
63-
fn clone(&self) -> Self {
64-
let inner = self.inner.clone();
65-
Self { inner }
68+
impl<T: #server_trait> Clone for #server_service<T> {
69+
fn clone(&self) -> Self {
70+
let inner = self.inner.clone();
71+
Self { inner }
72+
}
6673
}
67-
}
6874

69-
#transport
75+
#transport
76+
}
7077
}
7178
}
7279

tonic-examples/src/authentication/client.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ pub mod pb {
33
}
44

55
use http::header::HeaderValue;
6-
use pb::{client::EchoClient, EchoRequest};
6+
use pb::{echo_client::EchoClient, EchoRequest};
77
use tonic::transport::Channel;
88

99
#[tokio::main]

tonic-examples/src/authentication/server.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ type ResponseStream = Pin<Box<dyn Stream<Item = Result<EchoResponse, Status>> +
1515
pub struct EchoServer;
1616

1717
#[tonic::async_trait]
18-
impl pb::server::Echo for EchoServer {
18+
impl pb::echo_server::Echo for EchoServer {
1919
async fn unary_echo(&self, request: Request<EchoRequest>) -> EchoResult<EchoResponse> {
2020
let message = request.into_inner().message;
2121
Ok(Response::new(EchoResponse { message }))
@@ -79,7 +79,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
7979
}
8080
}
8181
})
82-
.add_service(pb::server::EchoServer::new(server))
82+
.add_service(pb::echo_server::EchoServer::new(server))
8383
.serve(addr)
8484
.await?;
8585

tonic-examples/src/gcp/client.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ pub mod api {
22
tonic::include_proto!("google.pubsub.v1");
33
}
44

5-
use api::{client::PublisherClient, ListTopicsRequest};
5+
use api::{publisher_client::PublisherClient, ListTopicsRequest};
66
use http::header::HeaderValue;
77
use tonic::{
88
transport::{Certificate, Channel, ClientTlsConfig},

tonic-examples/src/helloworld/client.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ pub mod hello_world {
22
tonic::include_proto!("helloworld");
33
}
44

5-
use hello_world::{client::GreeterClient, HelloRequest};
5+
use hello_world::{greeter_client::GreeterClient, HelloRequest};
66

77
#[tokio::main]
88
async fn main() -> Result<(), Box<dyn std::error::Error>> {

tonic-examples/src/helloworld/server.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ pub mod hello_world {
55
}
66

77
use hello_world::{
8-
server::{Greeter, GreeterServer},
8+
greeter_server::{Greeter, GreeterServer},
99
HelloReply, HelloRequest,
1010
};
1111

tonic-examples/src/load_balance/client.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ pub mod pb {
22
tonic::include_proto!("grpc.examples.echo");
33
}
44

5-
use pb::{client::EchoClient, EchoRequest};
5+
use pb::{echo_client::EchoClient, EchoRequest};
66
use tonic::transport::Channel;
77

88
#[tokio::main]

0 commit comments

Comments
 (0)