From 7c12e24fa9c2ea955397f690b6f861f6d641e45b Mon Sep 17 00:00:00 2001 From: Lukas Weber Date: Thu, 4 Jun 2026 16:51:23 +0200 Subject: [PATCH] feat(tonic-build): add ability to configure tonic crate path --- Cargo.toml | 2 + grpc/src/generated/grpc_examples_echo.rs | 156 ++++++++++-------- tests/tonic_path/my_application/Cargo.toml | 12 ++ tests/tonic_path/my_application/build.rs | 7 + tests/tonic_path/my_application/src/main.rs | 34 ++++ tests/tonic_path/proto/greeter/greeter.proto | 15 ++ tests/tonic_path/wrapper/Cargo.toml | 9 + tests/tonic_path/wrapper/src/lib.rs | 2 + tonic-build/src/client.rs | 80 +++++---- tonic-build/src/code_gen.rs | 19 +++ tonic-build/src/manual.rs | 31 +++- tonic-build/src/server.rs | 118 +++++++------ tonic-health/src/generated/grpc_health_v1.rs | 94 +++++------ tonic-prost-build/src/lib.rs | 27 ++- .../src/generated/grpc_reflection_v1.rs | 76 +++++---- .../src/generated/grpc_reflection_v1alpha.rs | 76 +++++---- 16 files changed, 483 insertions(+), 275 deletions(-) create mode 100644 tests/tonic_path/my_application/Cargo.toml create mode 100644 tests/tonic_path/my_application/build.rs create mode 100644 tests/tonic_path/my_application/src/main.rs create mode 100644 tests/tonic_path/proto/greeter/greeter.proto create mode 100644 tests/tonic_path/wrapper/Cargo.toml create mode 100644 tests/tonic_path/wrapper/src/lib.rs diff --git a/Cargo.toml b/Cargo.toml index dce26972f..131e05fcc 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -30,6 +30,8 @@ members = [ "tests/web", "tests/default_stubs", "tests/deprecated_methods", + "tests/tonic_path/wrapper", + "tests/tonic_path/my_application", ] resolver = "2" diff --git a/grpc/src/generated/grpc_examples_echo.rs b/grpc/src/generated/grpc_examples_echo.rs index 5545928b0..2c96a03e9 100644 --- a/grpc/src/generated/grpc_examples_echo.rs +++ b/grpc/src/generated/grpc_examples_echo.rs @@ -20,26 +20,26 @@ pub mod echo_client { clippy::wildcard_imports, clippy::let_unit_value, )] - use tonic::codegen::*; - use tonic::codegen::http::Uri; + use ::tonic::codegen::*; + use ::tonic::codegen::http::Uri; /// Echo is the echo service. #[derive(Debug, Clone)] pub struct EchoClient { - inner: tonic::client::Grpc, + inner: ::tonic::client::Grpc, } impl EchoClient where - T: tonic::client::GrpcService, + T: ::tonic::client::GrpcService<::tonic::body::Body>, T::Error: Into, T::ResponseBody: Body + std::marker::Send + 'static, ::Error: Into + std::marker::Send, { pub fn new(inner: T) -> Self { - let inner = tonic::client::Grpc::new(inner); + let inner = ::tonic::client::Grpc::new(inner); Self { inner } } pub fn with_origin(inner: T, origin: Uri) -> Self { - let inner = tonic::client::Grpc::with_origin(inner, origin); + let inner = ::tonic::client::Grpc::with_origin(inner, origin); Self { inner } } pub fn with_interceptor( @@ -47,16 +47,18 @@ pub mod echo_client { interceptor: F, ) -> EchoClient> where - F: tonic::service::Interceptor, + F: ::tonic::service::Interceptor, T::ResponseBody: Default, - T: tonic::codegen::Service< - http::Request, + T: ::tonic::codegen::Service< + http::Request<::tonic::body::Body>, Response = http::Response< - >::ResponseBody, + >::ResponseBody, >, >, - , + , >>::Error: Into + std::marker::Send + std::marker::Sync, { EchoClient::new(InterceptedService::new(inner, interceptor)) @@ -95,13 +97,16 @@ pub mod echo_client { /// UnaryEcho is unary echo. pub async fn unary_echo( &mut self, - request: impl tonic::IntoRequest, - ) -> std::result::Result, tonic::Status> { + request: impl ::tonic::IntoRequest, + ) -> std::result::Result< + ::tonic::Response, + ::tonic::Status, + > { self.inner .ready() .await .map_err(|e| { - tonic::Status::unknown( + ::tonic::Status::unknown( format!("Service was not ready: {}", e.into()), ) })?; @@ -117,16 +122,16 @@ pub mod echo_client { /// ServerStreamingEcho is server side streaming. pub async fn server_streaming_echo( &mut self, - request: impl tonic::IntoRequest, + request: impl ::tonic::IntoRequest, ) -> std::result::Result< - tonic::Response>, - tonic::Status, + ::tonic::Response<::tonic::codec::Streaming>, + ::tonic::Status, > { self.inner .ready() .await .map_err(|e| { - tonic::Status::unknown( + ::tonic::Status::unknown( format!("Service was not ready: {}", e.into()), ) })?; @@ -144,13 +149,16 @@ pub mod echo_client { /// ClientStreamingEcho is client side streaming. pub async fn client_streaming_echo( &mut self, - request: impl tonic::IntoStreamingRequest, - ) -> std::result::Result, tonic::Status> { + request: impl ::tonic::IntoStreamingRequest, + ) -> std::result::Result< + ::tonic::Response, + ::tonic::Status, + > { self.inner .ready() .await .map_err(|e| { - tonic::Status::unknown( + ::tonic::Status::unknown( format!("Service was not ready: {}", e.into()), ) })?; @@ -168,16 +176,16 @@ pub mod echo_client { /// BidirectionalStreamingEcho is bidi streaming. pub async fn bidirectional_streaming_echo( &mut self, - request: impl tonic::IntoStreamingRequest, + request: impl ::tonic::IntoStreamingRequest, ) -> std::result::Result< - tonic::Response>, - tonic::Status, + ::tonic::Response<::tonic::codec::Streaming>, + ::tonic::Status, > { self.inner .ready() .await .map_err(|e| { - tonic::Status::unknown( + ::tonic::Status::unknown( format!("Service was not ready: {}", e.into()), ) })?; @@ -206,47 +214,53 @@ pub mod echo_server { clippy::wildcard_imports, clippy::let_unit_value, )] - use tonic::codegen::*; + use ::tonic::codegen::*; /// Generated trait containing gRPC methods that should be implemented for use with EchoServer. #[async_trait] pub trait Echo: std::marker::Send + std::marker::Sync + 'static { /// UnaryEcho is unary echo. async fn unary_echo( &self, - request: tonic::Request, - ) -> std::result::Result, tonic::Status>; + request: ::tonic::Request, + ) -> std::result::Result< + ::tonic::Response, + ::tonic::Status, + >; /// Server streaming response type for the ServerStreamingEcho method. - type ServerStreamingEchoStream: tonic::codegen::tokio_stream::Stream< - Item = std::result::Result, + type ServerStreamingEchoStream: ::tonic::codegen::tokio_stream::Stream< + Item = std::result::Result, > + std::marker::Send + 'static; /// ServerStreamingEcho is server side streaming. async fn server_streaming_echo( &self, - request: tonic::Request, + request: ::tonic::Request, ) -> std::result::Result< - tonic::Response, - tonic::Status, + ::tonic::Response, + ::tonic::Status, >; /// ClientStreamingEcho is client side streaming. async fn client_streaming_echo( &self, - request: tonic::Request>, - ) -> std::result::Result, tonic::Status>; + request: ::tonic::Request<::tonic::Streaming>, + ) -> std::result::Result< + ::tonic::Response, + ::tonic::Status, + >; /// Server streaming response type for the BidirectionalStreamingEcho method. - type BidirectionalStreamingEchoStream: tonic::codegen::tokio_stream::Stream< - Item = std::result::Result, + type BidirectionalStreamingEchoStream: ::tonic::codegen::tokio_stream::Stream< + Item = std::result::Result, > + std::marker::Send + 'static; /// BidirectionalStreamingEcho is bidi streaming. async fn bidirectional_streaming_echo( &self, - request: tonic::Request>, + request: ::tonic::Request<::tonic::Streaming>, ) -> std::result::Result< - tonic::Response, - tonic::Status, + ::tonic::Response, + ::tonic::Status, >; } /// Echo is the echo service. @@ -276,7 +290,7 @@ pub mod echo_server { interceptor: F, ) -> InterceptedService where - F: tonic::service::Interceptor, + F: ::tonic::service::Interceptor, { InterceptedService::new(Self::new(inner), interceptor) } @@ -309,13 +323,13 @@ pub mod echo_server { self } } - impl tonic::codegen::Service> for EchoServer + impl ::tonic::codegen::Service> for EchoServer where T: Echo, B: Body + std::marker::Send + 'static, B::Error: Into + std::marker::Send + 'static, { - type Response = http::Response; + type Response = http::Response<::tonic::body::Body>; type Error = std::convert::Infallible; type Future = BoxFuture; fn poll_ready( @@ -329,16 +343,16 @@ pub mod echo_server { "/grpc.examples.echo.Echo/UnaryEcho" => { #[allow(non_camel_case_types)] struct UnaryEchoSvc(pub Arc); - impl tonic::server::UnaryService + impl ::tonic::server::UnaryService for UnaryEchoSvc { type Response = super::EchoResponse; type Future = BoxFuture< - tonic::Response, - tonic::Status, + ::tonic::Response, + ::tonic::Status, >; fn call( &mut self, - request: tonic::Request, + request: ::tonic::Request, ) -> Self::Future { let inner = Arc::clone(&self.0); let fut = async move { @@ -355,7 +369,7 @@ pub mod echo_server { let fut = async move { let method = UnaryEchoSvc(inner); let codec = tonic_prost::ProstCodec::default(); - let mut grpc = tonic::server::Grpc::new(codec) + let mut grpc = ::tonic::server::Grpc::new(codec) .apply_compression_config( accept_compression_encodings, send_compression_encodings, @@ -374,17 +388,17 @@ pub mod echo_server { struct ServerStreamingEchoSvc(pub Arc); impl< T: Echo, - > tonic::server::ServerStreamingService + > ::tonic::server::ServerStreamingService for ServerStreamingEchoSvc { type Response = super::EchoResponse; type ResponseStream = T::ServerStreamingEchoStream; type Future = BoxFuture< - tonic::Response, - tonic::Status, + ::tonic::Response, + ::tonic::Status, >; fn call( &mut self, - request: tonic::Request, + request: ::tonic::Request, ) -> Self::Future { let inner = Arc::clone(&self.0); let fut = async move { @@ -401,7 +415,7 @@ pub mod echo_server { let fut = async move { let method = ServerStreamingEchoSvc(inner); let codec = tonic_prost::ProstCodec::default(); - let mut grpc = tonic::server::Grpc::new(codec) + let mut grpc = ::tonic::server::Grpc::new(codec) .apply_compression_config( accept_compression_encodings, send_compression_encodings, @@ -420,16 +434,18 @@ pub mod echo_server { struct ClientStreamingEchoSvc(pub Arc); impl< T: Echo, - > tonic::server::ClientStreamingService + > ::tonic::server::ClientStreamingService for ClientStreamingEchoSvc { type Response = super::EchoResponse; type Future = BoxFuture< - tonic::Response, - tonic::Status, + ::tonic::Response, + ::tonic::Status, >; fn call( &mut self, - request: tonic::Request>, + request: ::tonic::Request< + ::tonic::Streaming, + >, ) -> Self::Future { let inner = Arc::clone(&self.0); let fut = async move { @@ -446,7 +462,7 @@ pub mod echo_server { let fut = async move { let method = ClientStreamingEchoSvc(inner); let codec = tonic_prost::ProstCodec::default(); - let mut grpc = tonic::server::Grpc::new(codec) + let mut grpc = ::tonic::server::Grpc::new(codec) .apply_compression_config( accept_compression_encodings, send_compression_encodings, @@ -463,17 +479,19 @@ pub mod echo_server { "/grpc.examples.echo.Echo/BidirectionalStreamingEcho" => { #[allow(non_camel_case_types)] struct BidirectionalStreamingEchoSvc(pub Arc); - impl tonic::server::StreamingService + impl ::tonic::server::StreamingService for BidirectionalStreamingEchoSvc { type Response = super::EchoResponse; type ResponseStream = T::BidirectionalStreamingEchoStream; type Future = BoxFuture< - tonic::Response, - tonic::Status, + ::tonic::Response, + ::tonic::Status, >; fn call( &mut self, - request: tonic::Request>, + request: ::tonic::Request< + ::tonic::Streaming, + >, ) -> Self::Future { let inner = Arc::clone(&self.0); let fut = async move { @@ -491,7 +509,7 @@ pub mod echo_server { let fut = async move { let method = BidirectionalStreamingEchoSvc(inner); let codec = tonic_prost::ProstCodec::default(); - let mut grpc = tonic::server::Grpc::new(codec) + let mut grpc = ::tonic::server::Grpc::new(codec) .apply_compression_config( accept_compression_encodings, send_compression_encodings, @@ -508,18 +526,18 @@ pub mod echo_server { _ => { Box::pin(async move { let mut response = http::Response::new( - tonic::body::Body::default(), + ::tonic::body::Body::default(), ); let headers = response.headers_mut(); headers .insert( - tonic::Status::GRPC_STATUS, - (tonic::Code::Unimplemented as i32).into(), + ::tonic::Status::GRPC_STATUS, + (::tonic::Code::Unimplemented as i32).into(), ); headers .insert( http::header::CONTENT_TYPE, - tonic::metadata::GRPC_CONTENT_TYPE, + ::tonic::metadata::GRPC_CONTENT_TYPE, ); Ok(response) }) @@ -541,7 +559,7 @@ pub mod echo_server { } /// Generated gRPC service name pub const SERVICE_NAME: &str = "grpc.examples.echo.Echo"; - impl tonic::server::NamedService for EchoServer { + impl ::tonic::server::NamedService for EchoServer { const NAME: &'static str = SERVICE_NAME; } } diff --git a/tests/tonic_path/my_application/Cargo.toml b/tests/tonic_path/my_application/Cargo.toml new file mode 100644 index 000000000..91b5257dc --- /dev/null +++ b/tests/tonic_path/my_application/Cargo.toml @@ -0,0 +1,12 @@ +[package] +name = "my_application_tonic_path" +edition = "2024" +license = "MIT" +publish = false + +[dependencies] +prost = "0.14" +wrapper = { path = "../wrapper" } + +[build-dependencies] +tonic-prost-build = { path = "../../../tonic-prost-build" } diff --git a/tests/tonic_path/my_application/build.rs b/tests/tonic_path/my_application/build.rs new file mode 100644 index 000000000..99b86b127 --- /dev/null +++ b/tests/tonic_path/my_application/build.rs @@ -0,0 +1,7 @@ +fn main() -> Result<(), std::io::Error> { + tonic_prost_build::configure() + .tonic_path("wrapper::tonic") + .codec_path("wrapper::tonic_prost::ProstCodec") + .compile_protos(&["greeter/greeter.proto"], &["../proto"])?; + Ok(()) +} diff --git a/tests/tonic_path/my_application/src/main.rs b/tests/tonic_path/my_application/src/main.rs new file mode 100644 index 000000000..a93c8b831 --- /dev/null +++ b/tests/tonic_path/my_application/src/main.rs @@ -0,0 +1,34 @@ +mod pb { + include!(concat!(env!("OUT_DIR"), "/greeter.rs")); +} + +#[derive(Default)] +struct MyGreeter; + +#[wrapper::tonic::async_trait] +impl pb::greeter_server::Greeter for MyGreeter { + async fn say_hello( + &self, + request: wrapper::tonic::Request, + ) -> Result, wrapper::tonic::Status> { + let name = request.into_inner().name; + Ok(wrapper::tonic::Response::new(pb::HelloResponse { + message: format!("Hello, {name}!"), + })) + } +} + +fn main() { + let _server = pb::greeter_server::GreeterServer::new(MyGreeter); +} + +#[cfg(test)] +#[test] +fn test_generated_types_resolve_through_wrapper() { + // Constructing both the server and client types proves the generated + // code resolved `wrapper::tonic::*` and `wrapper::tonic_prost::ProstCodec` + // without any direct `tonic` dependency in this crate's manifest. + let _server = pb::greeter_server::GreeterServer::new(MyGreeter); + fn _assert_client_type() {} + _assert_client_type::>(); +} diff --git a/tests/tonic_path/proto/greeter/greeter.proto b/tests/tonic_path/proto/greeter/greeter.proto new file mode 100644 index 000000000..ed8cc4e9e --- /dev/null +++ b/tests/tonic_path/proto/greeter/greeter.proto @@ -0,0 +1,15 @@ +syntax = "proto3"; + +package greeter; + +message HelloRequest { + string name = 1; +} + +message HelloResponse { + string message = 1; +} + +service Greeter { + rpc SayHello(HelloRequest) returns (HelloResponse); +} diff --git a/tests/tonic_path/wrapper/Cargo.toml b/tests/tonic_path/wrapper/Cargo.toml new file mode 100644 index 000000000..8f7d9c3fb --- /dev/null +++ b/tests/tonic_path/wrapper/Cargo.toml @@ -0,0 +1,9 @@ +[package] +name = "wrapper" +edition = "2024" +license = "MIT" +publish = false + +[dependencies] +tonic = { path = "../../../tonic" } +tonic-prost = { path = "../../../tonic-prost" } diff --git a/tests/tonic_path/wrapper/src/lib.rs b/tests/tonic_path/wrapper/src/lib.rs new file mode 100644 index 000000000..b63698e3a --- /dev/null +++ b/tests/tonic_path/wrapper/src/lib.rs @@ -0,0 +1,2 @@ +pub use ::tonic; +pub use ::tonic_prost; diff --git a/tonic-build/src/client.rs b/tonic-build/src/client.rs index 56c847585..9df329e33 100644 --- a/tonic-build/src/client.rs +++ b/tonic-build/src/client.rs @@ -8,6 +8,7 @@ use crate::{ use proc_macro2::TokenStream; use quote::{format_ident, quote}; +#[allow(clippy::too_many_arguments)] pub(crate) fn generate_internal( service: &T, emit_package: bool, @@ -16,6 +17,7 @@ pub(crate) fn generate_internal( build_transport: bool, attributes: &Attributes, disable_comments: &HashSet, + tonic_path: &syn::Path, ) -> TokenStream { let service_ident = quote::format_ident!("{}Client", service.name()); let client_mod = quote::format_ident!("{}_client", naive_snake_case(service.name())); @@ -25,9 +27,10 @@ pub(crate) fn generate_internal( proto_path, compile_well_known_types, disable_comments, + tonic_path, ); - let connect = generate_connect(&service_ident, build_transport); + let connect = generate_connect(&service_ident, build_transport, tonic_path); let package = if emit_package { service.package() } else { "" }; let service_name = format_service_name(service, emit_package); @@ -53,44 +56,44 @@ pub(crate) fn generate_internal( // will trigger if compression is disabled clippy::let_unit_value, )] - use tonic::codegen::*; - use tonic::codegen::http::Uri; + use #tonic_path::codegen::*; + use #tonic_path::codegen::http::Uri; #service_doc #(#struct_attributes)* #[derive(Debug, Clone)] pub struct #service_ident { - inner: tonic::client::Grpc, + inner: #tonic_path::client::Grpc, } #connect impl #service_ident where - T: tonic::client::GrpcService, + T: #tonic_path::client::GrpcService<#tonic_path::body::Body>, T::Error: Into, T::ResponseBody: Body + std::marker::Send + 'static, ::Error: Into + std::marker::Send, { pub fn new(inner: T) -> Self { - let inner = tonic::client::Grpc::new(inner); + let inner = #tonic_path::client::Grpc::new(inner); Self { inner } } pub fn with_origin(inner: T, origin: Uri) -> Self { - let inner = tonic::client::Grpc::with_origin(inner, origin); + let inner = #tonic_path::client::Grpc::with_origin(inner, origin); Self { inner } } pub fn with_interceptor(inner: T, interceptor: F) -> #service_ident> where - F: tonic::service::Interceptor, + F: #tonic_path::service::Interceptor, T::ResponseBody: Default, - T: tonic::codegen::Service< - http::Request, - Response = http::Response<>::ResponseBody> + T: #tonic_path::codegen::Service< + http::Request<#tonic_path::body::Body>, + Response = http::Response<>::ResponseBody> >, - >>::Error: Into + std::marker::Send + std::marker::Sync, + >>::Error: Into + std::marker::Send + std::marker::Sync, { #service_ident::new(InterceptedService::new(inner, interceptor)) } @@ -137,16 +140,20 @@ pub(crate) fn generate_internal( } #[cfg(feature = "transport")] -fn generate_connect(service_ident: &syn::Ident, enabled: bool) -> TokenStream { +fn generate_connect( + service_ident: &syn::Ident, + enabled: bool, + tonic_path: &syn::Path, +) -> TokenStream { let connect_impl = quote! { - impl #service_ident { + impl #service_ident<#tonic_path::transport::Channel> { /// Attempt to create a new client by connecting to a given endpoint. - pub async fn connect(dst: D) -> Result + pub async fn connect(dst: D) -> Result where - D: TryInto, + D: TryInto<#tonic_path::transport::Endpoint>, D::Error: Into, { - let conn = tonic::transport::Endpoint::new(dst)?.connect().await?; + let conn = #tonic_path::transport::Endpoint::new(dst)?.connect().await?; Ok(Self::new(conn)) } } @@ -160,7 +167,11 @@ fn generate_connect(service_ident: &syn::Ident, enabled: bool) -> TokenStream { } #[cfg(not(feature = "transport"))] -fn generate_connect(_service_ident: &syn::Ident, _enabled: bool) -> TokenStream { +fn generate_connect( + _service_ident: &syn::Ident, + _enabled: bool, + _tonic_path: &syn::Path, +) -> TokenStream { TokenStream::new() } @@ -170,6 +181,7 @@ fn generate_methods( proto_path: &str, compile_well_known_types: bool, disable_comments: &HashSet, + tonic_path: &syn::Path, ) -> TokenStream { let mut stream = TokenStream::new(); @@ -188,6 +200,7 @@ fn generate_methods( emit_package, proto_path, compile_well_known_types, + tonic_path, ), (false, true) => generate_server_streaming( service, @@ -195,6 +208,7 @@ fn generate_methods( emit_package, proto_path, compile_well_known_types, + tonic_path, ), (true, false) => generate_client_streaming( service, @@ -202,6 +216,7 @@ fn generate_methods( emit_package, proto_path, compile_well_known_types, + tonic_path, ), (true, true) => generate_streaming( service, @@ -209,6 +224,7 @@ fn generate_methods( emit_package, proto_path, compile_well_known_types, + tonic_path, ), }; @@ -224,6 +240,7 @@ fn generate_unary( emit_package: bool, proto_path: &str, compile_well_known_types: bool, + tonic_path: &syn::Path, ) -> TokenStream { let codec_name = syn::parse_str::(method.codec_path()).unwrap(); let ident = format_ident!("{}", method.name()); @@ -235,10 +252,10 @@ fn generate_unary( quote! { pub async fn #ident( &mut self, - request: impl tonic::IntoRequest<#request>, - ) -> std::result::Result, tonic::Status> { + request: impl #tonic_path::IntoRequest<#request>, + ) -> std::result::Result<#tonic_path::Response<#response>, #tonic_path::Status> { self.inner.ready().await.map_err(|e| { - tonic::Status::unknown(format!("Service was not ready: {}", e.into())) + #tonic_path::Status::unknown(format!("Service was not ready: {}", e.into())) })?; let codec = #codec_name::default(); let path = http::uri::PathAndQuery::from_static(#path); @@ -255,6 +272,7 @@ fn generate_server_streaming( emit_package: bool, proto_path: &str, compile_well_known_types: bool, + tonic_path: &syn::Path, ) -> TokenStream { let codec_name = syn::parse_str::(method.codec_path()).unwrap(); let ident = format_ident!("{}", method.name()); @@ -266,10 +284,10 @@ fn generate_server_streaming( quote! { pub async fn #ident( &mut self, - request: impl tonic::IntoRequest<#request>, - ) -> std::result::Result>, tonic::Status> { + request: impl #tonic_path::IntoRequest<#request>, + ) -> std::result::Result<#tonic_path::Response<#tonic_path::codec::Streaming<#response>>, #tonic_path::Status> { self.inner.ready().await.map_err(|e| { - tonic::Status::unknown(format!("Service was not ready: {}", e.into())) + #tonic_path::Status::unknown(format!("Service was not ready: {}", e.into())) })?; let codec = #codec_name::default(); let path = http::uri::PathAndQuery::from_static(#path); @@ -286,6 +304,7 @@ fn generate_client_streaming( emit_package: bool, proto_path: &str, compile_well_known_types: bool, + tonic_path: &syn::Path, ) -> TokenStream { let codec_name = syn::parse_str::(method.codec_path()).unwrap(); let ident = format_ident!("{}", method.name()); @@ -297,10 +316,10 @@ fn generate_client_streaming( quote! { pub async fn #ident( &mut self, - request: impl tonic::IntoStreamingRequest - ) -> std::result::Result, tonic::Status> { + request: impl #tonic_path::IntoStreamingRequest + ) -> std::result::Result<#tonic_path::Response<#response>, #tonic_path::Status> { self.inner.ready().await.map_err(|e| { - tonic::Status::unknown(format!("Service was not ready: {}", e.into())) + #tonic_path::Status::unknown(format!("Service was not ready: {}", e.into())) })?; let codec = #codec_name::default(); let path = http::uri::PathAndQuery::from_static(#path); @@ -317,6 +336,7 @@ fn generate_streaming( emit_package: bool, proto_path: &str, compile_well_known_types: bool, + tonic_path: &syn::Path, ) -> TokenStream { let codec_name = syn::parse_str::(method.codec_path()).unwrap(); let ident = format_ident!("{}", method.name()); @@ -328,10 +348,10 @@ fn generate_streaming( quote! { pub async fn #ident( &mut self, - request: impl tonic::IntoStreamingRequest - ) -> std::result::Result>, tonic::Status> { + request: impl #tonic_path::IntoStreamingRequest + ) -> std::result::Result<#tonic_path::Response<#tonic_path::codec::Streaming<#response>>, #tonic_path::Status> { self.inner.ready().await.map_err(|e| { - tonic::Status::unknown(format!("Service was not ready: {}", e.into())) + #tonic_path::Status::unknown(format!("Service was not ready: {}", e.into())) })?; let codec = #codec_name::default(); let path = http::uri::PathAndQuery::from_static(#path); diff --git a/tonic-build/src/code_gen.rs b/tonic-build/src/code_gen.rs index 87bb8d215..3d75edf5b 100644 --- a/tonic-build/src/code_gen.rs +++ b/tonic-build/src/code_gen.rs @@ -19,6 +19,7 @@ pub struct CodeGenBuilder { disable_comments: HashSet, use_arc_self: bool, generate_default_stubs: bool, + tonic_path: String, } impl CodeGenBuilder { @@ -70,6 +71,15 @@ impl CodeGenBuilder { self } + /// Set the path to the `tonic` crate for generated code. + /// + /// Useful for crates that re-export `tonic` under a different path (e.g. + /// `my_lib::tonic`). When unset, the default of `::tonic` is used. + pub fn tonic_path(&mut self, path: impl AsRef) -> &mut Self { + self.tonic_path = path.as_ref().to_string(); + self + } + /// Enable or disable returning automatic unimplemented gRPC error code for generated traits. pub fn generate_default_stubs(&mut self, generate_default_stubs: bool) -> &mut Self { self.generate_default_stubs = generate_default_stubs; @@ -81,6 +91,7 @@ impl CodeGenBuilder { /// This takes some `Service` and will generate a `TokenStream` that contains /// a public module with the generated client. pub fn generate_client(&self, service: &impl Service, proto_path: &str) -> TokenStream { + let tonic_path = self.parse_tonic_path(); crate::client::generate_internal( service, self.emit_package, @@ -89,6 +100,7 @@ impl CodeGenBuilder { self.build_transport, &self.attributes, &self.disable_comments, + &tonic_path, ) } @@ -97,6 +109,7 @@ impl CodeGenBuilder { /// This takes some `Service` and will generate a `TokenStream` that contains /// a public module with the generated client. pub fn generate_server(&self, service: &impl Service, proto_path: &str) -> TokenStream { + let tonic_path = self.parse_tonic_path(); crate::server::generate_internal( service, self.emit_package, @@ -106,8 +119,13 @@ impl CodeGenBuilder { &self.disable_comments, self.use_arc_self, self.generate_default_stubs, + &tonic_path, ) } + + fn parse_tonic_path(&self) -> syn::Path { + syn::parse_str(&self.tonic_path).expect("invalid tonic path") + } } impl Default for CodeGenBuilder { @@ -120,6 +138,7 @@ impl Default for CodeGenBuilder { disable_comments: HashSet::default(), use_arc_self: false, generate_default_stubs: false, + tonic_path: "::tonic".to_string(), } } } diff --git a/tonic-build/src/manual.rs b/tonic-build/src/manual.rs index 58b7b6914..fe8692a8e 100644 --- a/tonic-build/src/manual.rs +++ b/tonic-build/src/manual.rs @@ -361,20 +361,26 @@ struct ServiceGenerator { impl ServiceGenerator { fn generate(&mut self, service: &Service) { if self.builder.build_server { - let server = CodeGenBuilder::new() - .emit_package(true) - .compile_well_known_types(false) - .generate_server(service, ""); + let mut builder = CodeGenBuilder::new(); + builder.emit_package(true).compile_well_known_types(false); + if let Some(tonic_path) = &self.builder.tonic_path { + builder.tonic_path(tonic_path); + } + let server = builder.generate_server(service, ""); self.servers.extend(server); } if self.builder.build_client { - let client = CodeGenBuilder::new() + let mut builder = CodeGenBuilder::new(); + builder .emit_package(true) .compile_well_known_types(false) - .build_transport(self.builder.build_transport) - .generate_client(service, ""); + .build_transport(self.builder.build_transport); + if let Some(tonic_path) = &self.builder.tonic_path { + builder.tonic_path(tonic_path); + } + let client = builder.generate_client(service, ""); self.clients.extend(client); } @@ -419,6 +425,7 @@ pub struct Builder { build_transport: bool, out_dir: Option, + tonic_path: Option, } impl Default for Builder { @@ -428,6 +435,7 @@ impl Default for Builder { build_client: true, build_transport: true, out_dir: None, + tonic_path: None, } } } @@ -471,6 +479,15 @@ impl Builder { self } + /// Set the path to the `tonic` crate for generated code. + /// + /// Useful for crates that re-export `tonic` under a different path (e.g. + /// `my_lib::tonic`). When unset, the default of `::tonic` is used. + pub fn tonic_path(mut self, path: impl AsRef) -> Self { + self.tonic_path = Some(path.as_ref().to_string()); + self + } + /// Performs code generation for the provided services. /// /// Generated services will be output into the directory specified by `out_dir` diff --git a/tonic-build/src/server.rs b/tonic-build/src/server.rs index 1aa67b1b2..d9d27c835 100644 --- a/tonic-build/src/server.rs +++ b/tonic-build/src/server.rs @@ -19,6 +19,7 @@ pub(crate) fn generate_internal( disable_comments: &HashSet, use_arc_self: bool, generate_default_stubs: bool, + tonic_path: &syn::Path, ) -> TokenStream { let methods = generate_methods( service, @@ -27,6 +28,7 @@ pub(crate) fn generate_internal( compile_well_known_types, use_arc_self, generate_default_stubs, + tonic_path, ); let server_service = quote::format_ident!("{}Server", service.name()); @@ -43,6 +45,7 @@ pub(crate) fn generate_internal( use_arc_self, generate_default_stubs, trait_attributes, + tonic_path, ); let package = if emit_package { service.package() } else { "" }; // Transport based implementations @@ -54,7 +57,7 @@ pub(crate) fn generate_internal( generate_doc_comments(service.comment()) }; - let named = generate_named(&server_service, &service_name); + let named = generate_named(&server_service, &service_name, tonic_path); let mod_attributes = attributes.for_mod(package); let struct_attributes = attributes.for_struct(&service_name); @@ -106,7 +109,7 @@ pub(crate) fn generate_internal( // will trigger if compression is disabled clippy::let_unit_value, )] - use tonic::codegen::*; + use #tonic_path::codegen::*; #generated_trait @@ -138,7 +141,7 @@ pub(crate) fn generate_internal( pub fn with_interceptor(inner: T, interceptor: F) -> InterceptedService where - F: tonic::service::Interceptor, + F: #tonic_path::service::Interceptor, { InterceptedService::new(Self::new(inner), interceptor) } @@ -148,13 +151,13 @@ pub(crate) fn generate_internal( #configure_max_message_size_methods } - impl tonic::codegen::Service> for #server_service + impl #tonic_path::codegen::Service> for #server_service where T: #server_trait, B: Body + std::marker::Send + 'static, B::Error: Into + std::marker::Send + 'static, { - type Response = http::Response; + type Response = http::Response<#tonic_path::body::Body>; type Error = std::convert::Infallible; type Future = BoxFuture; @@ -167,10 +170,10 @@ pub(crate) fn generate_internal( #methods _ => Box::pin(async move { - let mut response = http::Response::new(tonic::body::Body::default()); + let mut response = http::Response::new(#tonic_path::body::Body::default()); let headers = response.headers_mut(); - headers.insert(tonic::Status::GRPC_STATUS, (tonic::Code::Unimplemented as i32).into()); - headers.insert(http::header::CONTENT_TYPE, tonic::metadata::GRPC_CONTENT_TYPE); + headers.insert(#tonic_path::Status::GRPC_STATUS, (#tonic_path::Code::Unimplemented as i32).into()); + headers.insert(http::header::CONTENT_TYPE, #tonic_path::metadata::GRPC_CONTENT_TYPE); Ok(response) }), } @@ -206,6 +209,7 @@ fn generate_trait( use_arc_self: bool, generate_default_stubs: bool, trait_attributes: Vec, + tonic_path: &syn::Path, ) -> TokenStream { let methods = generate_trait_methods( service, @@ -215,6 +219,7 @@ fn generate_trait( disable_comments, use_arc_self, generate_default_stubs, + tonic_path, ); let trait_doc = generate_doc_comment(format!( " Generated trait containing gRPC methods that should be implemented for use with {}Server.", @@ -231,6 +236,7 @@ fn generate_trait( } } +#[allow(clippy::too_many_arguments)] fn generate_trait_methods( service: &T, emit_package: bool, @@ -239,6 +245,7 @@ fn generate_trait_methods( disable_comments: &HashSet, use_arc_self: bool, generate_default_stubs: bool, + tonic_path: &syn::Path, ) -> TokenStream { let mut stream = TokenStream::new(); @@ -269,41 +276,41 @@ fn generate_trait_methods( (false, false, true) => { quote! { #method_doc - async fn #name(#self_param, request: tonic::Request<#req_message>) - -> std::result::Result, tonic::Status> { - Err(tonic::Status::unimplemented("Not yet implemented")) + async fn #name(#self_param, request: #tonic_path::Request<#req_message>) + -> std::result::Result<#tonic_path::Response<#res_message>, #tonic_path::Status> { + Err(#tonic_path::Status::unimplemented("Not yet implemented")) } } } (false, false, false) => { quote! { #method_doc - async fn #name(#self_param, request: tonic::Request<#req_message>) - -> std::result::Result, tonic::Status>; + async fn #name(#self_param, request: #tonic_path::Request<#req_message>) + -> std::result::Result<#tonic_path::Response<#res_message>, #tonic_path::Status>; } } (true, false, true) => { quote! { #method_doc - async fn #name(#self_param, request: tonic::Request>) - -> std::result::Result, tonic::Status> { - Err(tonic::Status::unimplemented("Not yet implemented")) + async fn #name(#self_param, request: #tonic_path::Request<#tonic_path::Streaming<#req_message>>) + -> std::result::Result<#tonic_path::Response<#res_message>, #tonic_path::Status> { + Err(#tonic_path::Status::unimplemented("Not yet implemented")) } } } (true, false, false) => { quote! { #method_doc - async fn #name(#self_param, request: tonic::Request>) - -> std::result::Result, tonic::Status>; + async fn #name(#self_param, request: #tonic_path::Request<#tonic_path::Streaming<#req_message>>) + -> std::result::Result<#tonic_path::Response<#res_message>, #tonic_path::Status>; } } (false, true, true) => { quote! { #method_doc - async fn #name(#self_param, request: tonic::Request<#req_message>) - -> std::result::Result>, tonic::Status> { - Err(tonic::Status::unimplemented("Not yet implemented")) + async fn #name(#self_param, request: #tonic_path::Request<#req_message>) + -> std::result::Result<#tonic_path::Response>, #tonic_path::Status> { + Err(#tonic_path::Status::unimplemented("Not yet implemented")) } } } @@ -316,19 +323,19 @@ fn generate_trait_methods( quote! { #stream_doc - type #stream: tonic::codegen::tokio_stream::Stream> + std::marker::Send + 'static; + type #stream: #tonic_path::codegen::tokio_stream::Stream> + std::marker::Send + 'static; #method_doc - async fn #name(#self_param, request: tonic::Request<#req_message>) - -> std::result::Result, tonic::Status>; + async fn #name(#self_param, request: #tonic_path::Request<#req_message>) + -> std::result::Result<#tonic_path::Response, #tonic_path::Status>; } } (true, true, true) => { quote! { #method_doc - async fn #name(#self_param, request: tonic::Request>) - -> std::result::Result>, tonic::Status> { - Err(tonic::Status::unimplemented("Not yet implemented")) + async fn #name(#self_param, request: #tonic_path::Request<#tonic_path::Streaming<#req_message>>) + -> std::result::Result<#tonic_path::Response>, #tonic_path::Status> { + Err(#tonic_path::Status::unimplemented("Not yet implemented")) } } } @@ -341,11 +348,11 @@ fn generate_trait_methods( quote! { #stream_doc - type #stream: tonic::codegen::tokio_stream::Stream> + std::marker::Send + 'static; + type #stream: #tonic_path::codegen::tokio_stream::Stream> + std::marker::Send + 'static; #method_doc - async fn #name(#self_param, request: tonic::Request>) - -> std::result::Result, tonic::Status>; + async fn #name(#self_param, request: #tonic_path::Request<#tonic_path::Streaming<#req_message>>) + -> std::result::Result<#tonic_path::Response, #tonic_path::Status>; } } }; @@ -356,7 +363,11 @@ fn generate_trait_methods( stream } -fn generate_named(server_service: &syn::Ident, service_name: &str) -> TokenStream { +fn generate_named( + server_service: &syn::Ident, + service_name: &str, + tonic_path: &syn::Path, +) -> TokenStream { let service_name = syn::LitStr::new(service_name, proc_macro2::Span::call_site()); let name_doc = generate_doc_comment(" Generated gRPC service name"); @@ -364,7 +375,7 @@ fn generate_named(server_service: &syn::Ident, service_name: &str) -> TokenStrea #name_doc pub const SERVICE_NAME: &str = #service_name; - impl tonic::server::NamedService for #server_service { + impl #tonic_path::server::NamedService for #server_service { const NAME: &'static str = SERVICE_NAME; } } @@ -377,6 +388,7 @@ fn generate_methods( compile_well_known_types: bool, use_arc_self: bool, generate_default_stubs: bool, + tonic_path: &syn::Path, ) -> TokenStream { let mut stream = TokenStream::new(); @@ -394,6 +406,7 @@ fn generate_methods( ident, server_trait, use_arc_self, + tonic_path, ), (false, true) => generate_server_streaming( @@ -404,6 +417,7 @@ fn generate_methods( server_trait, use_arc_self, generate_default_stubs, + tonic_path, ), (true, false) => generate_client_streaming( method, @@ -412,6 +426,7 @@ fn generate_methods( ident.clone(), server_trait, use_arc_self, + tonic_path, ), (true, true) => generate_streaming( @@ -422,6 +437,7 @@ fn generate_methods( server_trait, use_arc_self, generate_default_stubs, + tonic_path, ), }; @@ -443,6 +459,7 @@ fn generate_unary( method_ident: Ident, server_trait: Ident, use_arc_self: bool, + tonic_path: &syn::Path, ) -> TokenStream { let codec_name = syn::parse_str::(method.codec_path()).unwrap(); @@ -460,11 +477,11 @@ fn generate_unary( #[allow(non_camel_case_types)] struct #service_ident(pub Arc); - impl tonic::server::UnaryService<#request> for #service_ident { + impl #tonic_path::server::UnaryService<#request> for #service_ident { type Response = #response; - type Future = BoxFuture, tonic::Status>; + type Future = BoxFuture<#tonic_path::Response, #tonic_path::Status>; - fn call(&mut self, request: tonic::Request<#request>) -> Self::Future { + fn call(&mut self, request: #tonic_path::Request<#request>) -> Self::Future { let inner = Arc::clone(&self.0); let fut = async move { ::#method_ident(#inner_arg, request).await @@ -482,7 +499,7 @@ fn generate_unary( let method = #service_ident(inner); let codec = #codec_name::default(); - let mut grpc = tonic::server::Grpc::new(codec) + let mut grpc = #tonic_path::server::Grpc::new(codec) .apply_compression_config(accept_compression_encodings, send_compression_encodings) .apply_max_message_size_config(max_decoding_message_size, max_encoding_message_size); @@ -494,6 +511,7 @@ fn generate_unary( } } +#[allow(clippy::too_many_arguments)] fn generate_server_streaming( method: &T, proto_path: &str, @@ -502,6 +520,7 @@ fn generate_server_streaming( server_trait: Ident, use_arc_self: bool, generate_default_stubs: bool, + tonic_path: &syn::Path, ) -> TokenStream { let codec_name = syn::parse_str::(method.codec_path()).unwrap(); @@ -526,12 +545,12 @@ fn generate_server_streaming( #[allow(non_camel_case_types)] struct #service_ident(pub Arc); - impl tonic::server::ServerStreamingService<#request> for #service_ident { + impl #tonic_path::server::ServerStreamingService<#request> for #service_ident { type Response = #response; #response_stream; - type Future = BoxFuture, tonic::Status>; + type Future = BoxFuture<#tonic_path::Response, #tonic_path::Status>; - fn call(&mut self, request: tonic::Request<#request>) -> Self::Future { + fn call(&mut self, request: #tonic_path::Request<#request>) -> Self::Future { let inner = Arc::clone(&self.0); let fut = async move { ::#method_ident(#inner_arg, request).await @@ -549,7 +568,7 @@ fn generate_server_streaming( let method = #service_ident(inner); let codec = #codec_name::default(); - let mut grpc = tonic::server::Grpc::new(codec) + let mut grpc = #tonic_path::server::Grpc::new(codec) .apply_compression_config(accept_compression_encodings, send_compression_encodings) .apply_max_message_size_config(max_decoding_message_size, max_encoding_message_size); @@ -568,6 +587,7 @@ fn generate_client_streaming( method_ident: Ident, server_trait: Ident, use_arc_self: bool, + tonic_path: &syn::Path, ) -> TokenStream { let service_ident = quote::format_ident!("{}Svc", method.identifier()); @@ -584,12 +604,12 @@ fn generate_client_streaming( #[allow(non_camel_case_types)] struct #service_ident(pub Arc); - impl tonic::server::ClientStreamingService<#request> for #service_ident + impl #tonic_path::server::ClientStreamingService<#request> for #service_ident { type Response = #response; - type Future = BoxFuture, tonic::Status>; + type Future = BoxFuture<#tonic_path::Response, #tonic_path::Status>; - fn call(&mut self, request: tonic::Request>) -> Self::Future { + fn call(&mut self, request: #tonic_path::Request<#tonic_path::Streaming<#request>>) -> Self::Future { let inner = Arc::clone(&self.0); let fut = async move { ::#method_ident(#inner_arg, request).await @@ -607,7 +627,7 @@ fn generate_client_streaming( let method = #service_ident(inner); let codec = #codec_name::default(); - let mut grpc = tonic::server::Grpc::new(codec) + let mut grpc = #tonic_path::server::Grpc::new(codec) .apply_compression_config(accept_compression_encodings, send_compression_encodings) .apply_max_message_size_config(max_decoding_message_size, max_encoding_message_size); @@ -619,6 +639,7 @@ fn generate_client_streaming( } } +#[allow(clippy::too_many_arguments)] fn generate_streaming( method: &T, proto_path: &str, @@ -627,6 +648,7 @@ fn generate_streaming( server_trait: Ident, use_arc_self: bool, generate_default_stubs: bool, + tonic_path: &syn::Path, ) -> TokenStream { let codec_name = syn::parse_str::(method.codec_path()).unwrap(); @@ -651,13 +673,13 @@ fn generate_streaming( #[allow(non_camel_case_types)] struct #service_ident(pub Arc); - impl tonic::server::StreamingService<#request> for #service_ident + impl #tonic_path::server::StreamingService<#request> for #service_ident { type Response = #response; #response_stream; - type Future = BoxFuture, tonic::Status>; + type Future = BoxFuture<#tonic_path::Response, #tonic_path::Status>; - fn call(&mut self, request: tonic::Request>) -> Self::Future { + fn call(&mut self, request: #tonic_path::Request<#tonic_path::Streaming<#request>>) -> Self::Future { let inner = Arc::clone(&self.0); let fut = async move { ::#method_ident(#inner_arg, request).await @@ -675,7 +697,7 @@ fn generate_streaming( let method = #service_ident(inner); let codec = #codec_name::default(); - let mut grpc = tonic::server::Grpc::new(codec) + let mut grpc = #tonic_path::server::Grpc::new(codec) .apply_compression_config(accept_compression_encodings, send_compression_encodings) .apply_max_message_size_config(max_decoding_message_size, max_encoding_message_size); diff --git a/tonic-health/src/generated/grpc_health_v1.rs b/tonic-health/src/generated/grpc_health_v1.rs index 19cee943e..a86d627fd 100644 --- a/tonic-health/src/generated/grpc_health_v1.rs +++ b/tonic-health/src/generated/grpc_health_v1.rs @@ -64,25 +64,25 @@ pub mod health_client { clippy::wildcard_imports, clippy::let_unit_value, )] - use tonic::codegen::*; - use tonic::codegen::http::Uri; + use ::tonic::codegen::*; + use ::tonic::codegen::http::Uri; #[derive(Debug, Clone)] pub struct HealthClient { - inner: tonic::client::Grpc, + inner: ::tonic::client::Grpc, } impl HealthClient where - T: tonic::client::GrpcService, + T: ::tonic::client::GrpcService<::tonic::body::Body>, T::Error: Into, T::ResponseBody: Body + std::marker::Send + 'static, ::Error: Into + std::marker::Send, { pub fn new(inner: T) -> Self { - let inner = tonic::client::Grpc::new(inner); + let inner = ::tonic::client::Grpc::new(inner); Self { inner } } pub fn with_origin(inner: T, origin: Uri) -> Self { - let inner = tonic::client::Grpc::with_origin(inner, origin); + let inner = ::tonic::client::Grpc::with_origin(inner, origin); Self { inner } } pub fn with_interceptor( @@ -90,16 +90,18 @@ pub mod health_client { interceptor: F, ) -> HealthClient> where - F: tonic::service::Interceptor, + F: ::tonic::service::Interceptor, T::ResponseBody: Default, - T: tonic::codegen::Service< - http::Request, + T: ::tonic::codegen::Service< + http::Request<::tonic::body::Body>, Response = http::Response< - >::ResponseBody, + >::ResponseBody, >, >, - , + , >>::Error: Into + std::marker::Send + std::marker::Sync, { HealthClient::new(InterceptedService::new(inner, interceptor)) @@ -139,16 +141,16 @@ pub mod health_client { /// NOT_FOUND. pub async fn check( &mut self, - request: impl tonic::IntoRequest, + request: impl ::tonic::IntoRequest, ) -> std::result::Result< - tonic::Response, - tonic::Status, + ::tonic::Response, + ::tonic::Status, > { self.inner .ready() .await .map_err(|e| { - tonic::Status::unknown( + ::tonic::Status::unknown( format!("Service was not ready: {}", e.into()), ) })?; @@ -178,16 +180,16 @@ pub mod health_client { /// clients should retry the call with appropriate exponential backoff. pub async fn watch( &mut self, - request: impl tonic::IntoRequest, + request: impl ::tonic::IntoRequest, ) -> std::result::Result< - tonic::Response>, - tonic::Status, + ::tonic::Response<::tonic::codec::Streaming>, + ::tonic::Status, > { self.inner .ready() .await .map_err(|e| { - tonic::Status::unknown( + ::tonic::Status::unknown( format!("Service was not ready: {}", e.into()), ) })?; @@ -211,7 +213,7 @@ pub mod health_server { clippy::wildcard_imports, clippy::let_unit_value, )] - use tonic::codegen::*; + use ::tonic::codegen::*; /// Generated trait containing gRPC methods that should be implemented for use with HealthServer. #[async_trait] pub trait Health: std::marker::Send + std::marker::Sync + 'static { @@ -219,14 +221,14 @@ pub mod health_server { /// NOT_FOUND. async fn check( &self, - request: tonic::Request, + request: ::tonic::Request, ) -> std::result::Result< - tonic::Response, - tonic::Status, + ::tonic::Response, + ::tonic::Status, >; /// Server streaming response type for the Watch method. - type WatchStream: tonic::codegen::tokio_stream::Stream< - Item = std::result::Result, + type WatchStream: ::tonic::codegen::tokio_stream::Stream< + Item = std::result::Result, > + std::marker::Send + 'static; @@ -247,8 +249,8 @@ pub mod health_server { /// clients should retry the call with appropriate exponential backoff. async fn watch( &self, - request: tonic::Request, - ) -> std::result::Result, tonic::Status>; + request: ::tonic::Request, + ) -> std::result::Result<::tonic::Response, ::tonic::Status>; } #[derive(Debug)] pub struct HealthServer { @@ -276,7 +278,7 @@ pub mod health_server { interceptor: F, ) -> InterceptedService where - F: tonic::service::Interceptor, + F: ::tonic::service::Interceptor, { InterceptedService::new(Self::new(inner), interceptor) } @@ -309,13 +311,13 @@ pub mod health_server { self } } - impl tonic::codegen::Service> for HealthServer + impl ::tonic::codegen::Service> for HealthServer where T: Health, B: Body + std::marker::Send + 'static, B::Error: Into + std::marker::Send + 'static, { - type Response = http::Response; + type Response = http::Response<::tonic::body::Body>; type Error = std::convert::Infallible; type Future = BoxFuture; fn poll_ready( @@ -331,16 +333,16 @@ pub mod health_server { struct CheckSvc(pub Arc); impl< T: Health, - > tonic::server::UnaryService + > ::tonic::server::UnaryService for CheckSvc { type Response = super::HealthCheckResponse; type Future = BoxFuture< - tonic::Response, - tonic::Status, + ::tonic::Response, + ::tonic::Status, >; fn call( &mut self, - request: tonic::Request, + request: ::tonic::Request, ) -> Self::Future { let inner = Arc::clone(&self.0); let fut = async move { @@ -357,7 +359,7 @@ pub mod health_server { let fut = async move { let method = CheckSvc(inner); let codec = tonic_prost::ProstCodec::default(); - let mut grpc = tonic::server::Grpc::new(codec) + let mut grpc = ::tonic::server::Grpc::new(codec) .apply_compression_config( accept_compression_encodings, send_compression_encodings, @@ -376,17 +378,17 @@ pub mod health_server { struct WatchSvc(pub Arc); impl< T: Health, - > tonic::server::ServerStreamingService + > ::tonic::server::ServerStreamingService for WatchSvc { type Response = super::HealthCheckResponse; type ResponseStream = T::WatchStream; type Future = BoxFuture< - tonic::Response, - tonic::Status, + ::tonic::Response, + ::tonic::Status, >; fn call( &mut self, - request: tonic::Request, + request: ::tonic::Request, ) -> Self::Future { let inner = Arc::clone(&self.0); let fut = async move { @@ -403,7 +405,7 @@ pub mod health_server { let fut = async move { let method = WatchSvc(inner); let codec = tonic_prost::ProstCodec::default(); - let mut grpc = tonic::server::Grpc::new(codec) + let mut grpc = ::tonic::server::Grpc::new(codec) .apply_compression_config( accept_compression_encodings, send_compression_encodings, @@ -420,18 +422,18 @@ pub mod health_server { _ => { Box::pin(async move { let mut response = http::Response::new( - tonic::body::Body::default(), + ::tonic::body::Body::default(), ); let headers = response.headers_mut(); headers .insert( - tonic::Status::GRPC_STATUS, - (tonic::Code::Unimplemented as i32).into(), + ::tonic::Status::GRPC_STATUS, + (::tonic::Code::Unimplemented as i32).into(), ); headers .insert( http::header::CONTENT_TYPE, - tonic::metadata::GRPC_CONTENT_TYPE, + ::tonic::metadata::GRPC_CONTENT_TYPE, ); Ok(response) }) @@ -453,7 +455,7 @@ pub mod health_server { } /// Generated gRPC service name pub const SERVICE_NAME: &str = "grpc.health.v1.Health"; - impl tonic::server::NamedService for HealthServer { + impl ::tonic::server::NamedService for HealthServer { const NAME: &'static str = SERVICE_NAME; } } diff --git a/tonic-prost-build/src/lib.rs b/tonic-prost-build/src/lib.rs index 055b511d7..d8abbc022 100644 --- a/tonic-prost-build/src/lib.rs +++ b/tonic-prost-build/src/lib.rs @@ -85,6 +85,7 @@ pub fn configure() -> Builder { use_arc_self: false, generate_default_stubs: false, codec_path: "tonic_prost::ProstCodec".to_string(), + tonic_path: None, skip_debug: HashSet::default(), } } @@ -328,6 +329,7 @@ struct ServiceGenerator { proto_path: String, compile_well_known_types: bool, codec_path: String, + tonic_path: Option, disable_comments: HashSet, } @@ -345,6 +347,7 @@ impl ServiceGenerator { proto_path: String, compile_well_known_types: bool, codec_path: String, + tonic_path: Option, disable_comments: HashSet, ) -> Self { ServiceGenerator { @@ -358,6 +361,7 @@ impl ServiceGenerator { proto_path, compile_well_known_types, codec_path, + tonic_path, disable_comments, } } @@ -376,6 +380,10 @@ impl prost_build::ServiceGenerator for ServiceGenerator { .use_arc_self(self.use_arc_self) .generate_default_stubs(self.generate_default_stubs); + if let Some(p) = &self.tonic_path { + builder.tonic_path(p); + } + let mut tokens = TokenStream::new(); if self.build_client { @@ -425,6 +433,7 @@ pub struct Builder { use_arc_self: bool, generate_default_stubs: bool, codec_path: String, + tonic_path: Option, skip_debug: HashSet, } @@ -700,6 +709,15 @@ impl Builder { self } + /// Set the path to the `tonic` crate for generated code. + /// + /// Useful for crates that re-export `tonic` under a different path (e.g. + /// `my_lib::tonic`). When unset, the default of `::tonic` is used. + pub fn tonic_path(mut self, path: impl AsRef) -> Self { + self.tonic_path = Some(path.as_ref().to_string()); + self + } + /// Configure the code generator not to strip the `Debug` implementation for the request and /// response types from the generated code. /// @@ -829,7 +847,8 @@ impl Builder { self.generate_default_stubs, self.proto_path, self.compile_well_known_types, - self.codec_path.clone(), + self.codec_path, + self.tonic_path, self.disable_comments, ); @@ -931,7 +950,8 @@ impl Builder { self.generate_default_stubs, self.proto_path, self.compile_well_known_types, - self.codec_path.clone(), + self.codec_path, + self.tonic_path, self.disable_comments, ); @@ -956,7 +976,8 @@ impl Builder { self.generate_default_stubs, self.proto_path, self.compile_well_known_types, - self.codec_path.clone(), + self.codec_path, + self.tonic_path, self.disable_comments, )) } diff --git a/tonic-reflection/src/generated/grpc_reflection_v1.rs b/tonic-reflection/src/generated/grpc_reflection_v1.rs index a78eaf20c..0007a0f14 100644 --- a/tonic-reflection/src/generated/grpc_reflection_v1.rs +++ b/tonic-reflection/src/generated/grpc_reflection_v1.rs @@ -153,25 +153,25 @@ pub mod server_reflection_client { clippy::wildcard_imports, clippy::let_unit_value, )] - use tonic::codegen::*; - use tonic::codegen::http::Uri; + use ::tonic::codegen::*; + use ::tonic::codegen::http::Uri; #[derive(Debug, Clone)] pub struct ServerReflectionClient { - inner: tonic::client::Grpc, + inner: ::tonic::client::Grpc, } impl ServerReflectionClient where - T: tonic::client::GrpcService, + T: ::tonic::client::GrpcService<::tonic::body::Body>, T::Error: Into, T::ResponseBody: Body + std::marker::Send + 'static, ::Error: Into + std::marker::Send, { pub fn new(inner: T) -> Self { - let inner = tonic::client::Grpc::new(inner); + let inner = ::tonic::client::Grpc::new(inner); Self { inner } } pub fn with_origin(inner: T, origin: Uri) -> Self { - let inner = tonic::client::Grpc::with_origin(inner, origin); + let inner = ::tonic::client::Grpc::with_origin(inner, origin); Self { inner } } pub fn with_interceptor( @@ -179,16 +179,18 @@ pub mod server_reflection_client { interceptor: F, ) -> ServerReflectionClient> where - F: tonic::service::Interceptor, + F: ::tonic::service::Interceptor, T::ResponseBody: Default, - T: tonic::codegen::Service< - http::Request, + T: ::tonic::codegen::Service< + http::Request<::tonic::body::Body>, Response = http::Response< - >::ResponseBody, + >::ResponseBody, >, >, - , + , >>::Error: Into + std::marker::Send + std::marker::Sync, { ServerReflectionClient::new(InterceptedService::new(inner, interceptor)) @@ -228,18 +230,20 @@ pub mod server_reflection_client { /// all related requests go to a single server. pub async fn server_reflection_info( &mut self, - request: impl tonic::IntoStreamingRequest< + request: impl ::tonic::IntoStreamingRequest< Message = super::ServerReflectionRequest, >, ) -> std::result::Result< - tonic::Response>, - tonic::Status, + ::tonic::Response< + ::tonic::codec::Streaming, + >, + ::tonic::Status, > { self.inner .ready() .await .map_err(|e| { - tonic::Status::unknown( + ::tonic::Status::unknown( format!("Service was not ready: {}", e.into()), ) })?; @@ -268,15 +272,15 @@ pub mod server_reflection_server { clippy::wildcard_imports, clippy::let_unit_value, )] - use tonic::codegen::*; + use ::tonic::codegen::*; /// Generated trait containing gRPC methods that should be implemented for use with ServerReflectionServer. #[async_trait] pub trait ServerReflection: std::marker::Send + std::marker::Sync + 'static { /// Server streaming response type for the ServerReflectionInfo method. - type ServerReflectionInfoStream: tonic::codegen::tokio_stream::Stream< + type ServerReflectionInfoStream: ::tonic::codegen::tokio_stream::Stream< Item = std::result::Result< super::ServerReflectionResponse, - tonic::Status, + ::tonic::Status, >, > + std::marker::Send @@ -285,10 +289,10 @@ pub mod server_reflection_server { /// all related requests go to a single server. async fn server_reflection_info( &self, - request: tonic::Request>, + request: ::tonic::Request<::tonic::Streaming>, ) -> std::result::Result< - tonic::Response, - tonic::Status, + ::tonic::Response, + ::tonic::Status, >; } #[derive(Debug)] @@ -317,7 +321,7 @@ pub mod server_reflection_server { interceptor: F, ) -> InterceptedService where - F: tonic::service::Interceptor, + F: ::tonic::service::Interceptor, { InterceptedService::new(Self::new(inner), interceptor) } @@ -350,13 +354,13 @@ pub mod server_reflection_server { self } } - impl tonic::codegen::Service> for ServerReflectionServer + impl ::tonic::codegen::Service> for ServerReflectionServer where T: ServerReflection, B: Body + std::marker::Send + 'static, B::Error: Into + std::marker::Send + 'static, { - type Response = http::Response; + type Response = http::Response<::tonic::body::Body>; type Error = std::convert::Infallible; type Future = BoxFuture; fn poll_ready( @@ -372,18 +376,18 @@ pub mod server_reflection_server { struct ServerReflectionInfoSvc(pub Arc); impl< T: ServerReflection, - > tonic::server::StreamingService + > ::tonic::server::StreamingService for ServerReflectionInfoSvc { type Response = super::ServerReflectionResponse; type ResponseStream = T::ServerReflectionInfoStream; type Future = BoxFuture< - tonic::Response, - tonic::Status, + ::tonic::Response, + ::tonic::Status, >; fn call( &mut self, - request: tonic::Request< - tonic::Streaming, + request: ::tonic::Request< + ::tonic::Streaming, >, ) -> Self::Future { let inner = Arc::clone(&self.0); @@ -405,7 +409,7 @@ pub mod server_reflection_server { let fut = async move { let method = ServerReflectionInfoSvc(inner); let codec = tonic_prost::ProstCodec::default(); - let mut grpc = tonic::server::Grpc::new(codec) + let mut grpc = ::tonic::server::Grpc::new(codec) .apply_compression_config( accept_compression_encodings, send_compression_encodings, @@ -422,18 +426,18 @@ pub mod server_reflection_server { _ => { Box::pin(async move { let mut response = http::Response::new( - tonic::body::Body::default(), + ::tonic::body::Body::default(), ); let headers = response.headers_mut(); headers .insert( - tonic::Status::GRPC_STATUS, - (tonic::Code::Unimplemented as i32).into(), + ::tonic::Status::GRPC_STATUS, + (::tonic::Code::Unimplemented as i32).into(), ); headers .insert( http::header::CONTENT_TYPE, - tonic::metadata::GRPC_CONTENT_TYPE, + ::tonic::metadata::GRPC_CONTENT_TYPE, ); Ok(response) }) @@ -455,7 +459,7 @@ pub mod server_reflection_server { } /// Generated gRPC service name pub const SERVICE_NAME: &str = "grpc.reflection.v1.ServerReflection"; - impl tonic::server::NamedService for ServerReflectionServer { + impl ::tonic::server::NamedService for ServerReflectionServer { const NAME: &'static str = SERVICE_NAME; } } diff --git a/tonic-reflection/src/generated/grpc_reflection_v1alpha.rs b/tonic-reflection/src/generated/grpc_reflection_v1alpha.rs index b2afc7f6a..20540d10b 100644 --- a/tonic-reflection/src/generated/grpc_reflection_v1alpha.rs +++ b/tonic-reflection/src/generated/grpc_reflection_v1alpha.rs @@ -153,25 +153,25 @@ pub mod server_reflection_client { clippy::wildcard_imports, clippy::let_unit_value, )] - use tonic::codegen::*; - use tonic::codegen::http::Uri; + use ::tonic::codegen::*; + use ::tonic::codegen::http::Uri; #[derive(Debug, Clone)] pub struct ServerReflectionClient { - inner: tonic::client::Grpc, + inner: ::tonic::client::Grpc, } impl ServerReflectionClient where - T: tonic::client::GrpcService, + T: ::tonic::client::GrpcService<::tonic::body::Body>, T::Error: Into, T::ResponseBody: Body + std::marker::Send + 'static, ::Error: Into + std::marker::Send, { pub fn new(inner: T) -> Self { - let inner = tonic::client::Grpc::new(inner); + let inner = ::tonic::client::Grpc::new(inner); Self { inner } } pub fn with_origin(inner: T, origin: Uri) -> Self { - let inner = tonic::client::Grpc::with_origin(inner, origin); + let inner = ::tonic::client::Grpc::with_origin(inner, origin); Self { inner } } pub fn with_interceptor( @@ -179,16 +179,18 @@ pub mod server_reflection_client { interceptor: F, ) -> ServerReflectionClient> where - F: tonic::service::Interceptor, + F: ::tonic::service::Interceptor, T::ResponseBody: Default, - T: tonic::codegen::Service< - http::Request, + T: ::tonic::codegen::Service< + http::Request<::tonic::body::Body>, Response = http::Response< - >::ResponseBody, + >::ResponseBody, >, >, - , + , >>::Error: Into + std::marker::Send + std::marker::Sync, { ServerReflectionClient::new(InterceptedService::new(inner, interceptor)) @@ -228,18 +230,20 @@ pub mod server_reflection_client { /// all related requests go to a single server. pub async fn server_reflection_info( &mut self, - request: impl tonic::IntoStreamingRequest< + request: impl ::tonic::IntoStreamingRequest< Message = super::ServerReflectionRequest, >, ) -> std::result::Result< - tonic::Response>, - tonic::Status, + ::tonic::Response< + ::tonic::codec::Streaming, + >, + ::tonic::Status, > { self.inner .ready() .await .map_err(|e| { - tonic::Status::unknown( + ::tonic::Status::unknown( format!("Service was not ready: {}", e.into()), ) })?; @@ -268,15 +272,15 @@ pub mod server_reflection_server { clippy::wildcard_imports, clippy::let_unit_value, )] - use tonic::codegen::*; + use ::tonic::codegen::*; /// Generated trait containing gRPC methods that should be implemented for use with ServerReflectionServer. #[async_trait] pub trait ServerReflection: std::marker::Send + std::marker::Sync + 'static { /// Server streaming response type for the ServerReflectionInfo method. - type ServerReflectionInfoStream: tonic::codegen::tokio_stream::Stream< + type ServerReflectionInfoStream: ::tonic::codegen::tokio_stream::Stream< Item = std::result::Result< super::ServerReflectionResponse, - tonic::Status, + ::tonic::Status, >, > + std::marker::Send @@ -285,10 +289,10 @@ pub mod server_reflection_server { /// all related requests go to a single server. async fn server_reflection_info( &self, - request: tonic::Request>, + request: ::tonic::Request<::tonic::Streaming>, ) -> std::result::Result< - tonic::Response, - tonic::Status, + ::tonic::Response, + ::tonic::Status, >; } #[derive(Debug)] @@ -317,7 +321,7 @@ pub mod server_reflection_server { interceptor: F, ) -> InterceptedService where - F: tonic::service::Interceptor, + F: ::tonic::service::Interceptor, { InterceptedService::new(Self::new(inner), interceptor) } @@ -350,13 +354,13 @@ pub mod server_reflection_server { self } } - impl tonic::codegen::Service> for ServerReflectionServer + impl ::tonic::codegen::Service> for ServerReflectionServer where T: ServerReflection, B: Body + std::marker::Send + 'static, B::Error: Into + std::marker::Send + 'static, { - type Response = http::Response; + type Response = http::Response<::tonic::body::Body>; type Error = std::convert::Infallible; type Future = BoxFuture; fn poll_ready( @@ -372,18 +376,18 @@ pub mod server_reflection_server { struct ServerReflectionInfoSvc(pub Arc); impl< T: ServerReflection, - > tonic::server::StreamingService + > ::tonic::server::StreamingService for ServerReflectionInfoSvc { type Response = super::ServerReflectionResponse; type ResponseStream = T::ServerReflectionInfoStream; type Future = BoxFuture< - tonic::Response, - tonic::Status, + ::tonic::Response, + ::tonic::Status, >; fn call( &mut self, - request: tonic::Request< - tonic::Streaming, + request: ::tonic::Request< + ::tonic::Streaming, >, ) -> Self::Future { let inner = Arc::clone(&self.0); @@ -405,7 +409,7 @@ pub mod server_reflection_server { let fut = async move { let method = ServerReflectionInfoSvc(inner); let codec = tonic_prost::ProstCodec::default(); - let mut grpc = tonic::server::Grpc::new(codec) + let mut grpc = ::tonic::server::Grpc::new(codec) .apply_compression_config( accept_compression_encodings, send_compression_encodings, @@ -422,18 +426,18 @@ pub mod server_reflection_server { _ => { Box::pin(async move { let mut response = http::Response::new( - tonic::body::Body::default(), + ::tonic::body::Body::default(), ); let headers = response.headers_mut(); headers .insert( - tonic::Status::GRPC_STATUS, - (tonic::Code::Unimplemented as i32).into(), + ::tonic::Status::GRPC_STATUS, + (::tonic::Code::Unimplemented as i32).into(), ); headers .insert( http::header::CONTENT_TYPE, - tonic::metadata::GRPC_CONTENT_TYPE, + ::tonic::metadata::GRPC_CONTENT_TYPE, ); Ok(response) }) @@ -455,7 +459,7 @@ pub mod server_reflection_server { } /// Generated gRPC service name pub const SERVICE_NAME: &str = "grpc.reflection.v1alpha.ServerReflection"; - impl tonic::server::NamedService for ServerReflectionServer { + impl ::tonic::server::NamedService for ServerReflectionServer { const NAME: &'static str = SERVICE_NAME; } }