diff --git a/tonic-build/src/client.rs b/tonic-build/src/client.rs index 06bbe6a..f78aeb4 100644 --- a/tonic-build/src/client.rs +++ b/tonic-build/src/client.rs @@ -8,18 +8,16 @@ pub(crate) fn generate(service: &Service, proto: &str) -> TokenStream { let methods = generate_methods(service, proto); quote! { - use tonic::_codegen::*; - - pub struct #service_ident { + pub struct #service_ident { inner: tonic::client::Grpc, } - impl #service_ident + impl #service_ident where T: tonic::client::GrpcService, - T::ResponseBody: tonic::body::Body + tonic::_codegen::HttpBody + Send + 'static, - T::Error: Into, - ::Error: Into + Send, - ::Data: Into + Send, { + T::ResponseBody: Body + HttpBody + Send + 'static, + T::Error: Into, + ::Error: Into + Send, + ::Data: Into + Send, { pub fn new(inner: T) -> Self { let inner = tonic::client::Grpc::new(inner); Self { inner } @@ -34,7 +32,7 @@ pub(crate) fn generate(service: &Service, proto: &str) -> TokenStream { #methods } - impl Clone for #service_ident { + impl Clone for #service_ident { fn clone(&self) -> Self { Self { inner: self.inner.clone(), @@ -72,7 +70,7 @@ fn generate_unary(method: &Method, proto: &str, path: String) -> TokenStream { let response: Path = syn::parse_str(&format!("{}::{}", proto, method.output_type)).unwrap(); quote! { - pub async fn #ident (&mut self, request: tonic::Request<#request>) + pub async fn #ident(&mut self, request: tonic::Request<#request>) -> Result, tonic::Status> { self.ready().await?; let codec = tonic::codec::ProstCodec::new(); @@ -88,7 +86,7 @@ fn generate_server_streaming(method: &Method, proto: &str, path: String) -> Toke let response: Path = syn::parse_str(&format!("{}::{}", proto, method.output_type)).unwrap(); quote! { - pub async fn #ident (&mut self, request: tonic::Request<#request>) + pub async fn #ident(&mut self, request: tonic::Request<#request>) -> Result>, tonic::Status> { self.ready().await?; let codec = tonic::codec::ProstCodec::new(); @@ -104,14 +102,13 @@ fn generate_client_streaming(method: &Method, proto: &str, path: String) -> Toke let response: Path = syn::parse_str(&format!("{}::{}", proto, method.output_type)).unwrap(); quote! { - pub async fn #ident (&mut self, request: tonic::Request) + pub async fn #ident(&mut self, request: tonic::Request) -> Result, tonic::Status> - where S: tonic::_codegen::Stream> + Send + 'static, + where S: Stream> + Send + 'static, { self.ready().await?; let codec = tonic::codec::ProstCodec::new(); let path = http::uri::PathAndQuery::from_static(#path); - let request = request.map(|s| Box::pin(s)); self.inner.client_streaming(request, path, codec).await } } @@ -123,14 +120,13 @@ fn generate_streaming(method: &Method, proto: &str, path: String) -> TokenStream let response: Path = syn::parse_str(&format!("{}::{}", proto, method.output_type)).unwrap(); quote! { - pub async fn #ident (&mut self, request: tonic::Request) + pub async fn #ident(&mut self, request: tonic::Request) -> Result>, tonic::Status> - where S: tonic::_codegen::Stream> + Send + 'static, + where S: Stream> + Send + 'static, { self.ready().await?; let codec = tonic::codec::ProstCodec::new(); let path = http::uri::PathAndQuery::from_static(#path); - let request = request.map(|s| Box::pin(s)); self.inner.streaming(request, path, codec).await } } diff --git a/tonic-build/src/lib.rs b/tonic-build/src/lib.rs index a62c426..ca795a7 100644 --- a/tonic-build/src/lib.rs +++ b/tonic-build/src/lib.rs @@ -1,3 +1,18 @@ +//! `tonic-build` compiles `proto` files via `prost` and generates service stubs +//! and proto definitiones for use with `tonic`. +//! +//! # Examples +//! +//! ```rust,no_run +//! fn main() { +//! tonic_build::compile_protos( +//! &["proto/helloworld/helloworld.proto"], +//! &["proto/helloworld"], +//! "helloworld", +//! ) +//! .unwrap(); +//! } + use proc_macro2::TokenStream; use prost_build::Config; use std::{io, path, path::Path, process::Command}; @@ -72,12 +87,14 @@ impl prost_build::ServiceGenerator for ServiceGenerator { let service = quote::quote! { pub mod client { #![allow(unused_variables, dead_code, missing_docs)] + use tonic::codegen::*; #clients } pub mod server { #![allow(unused_variables, dead_code, missing_docs)] + use tonic::codegen::*; #servers } diff --git a/tonic-build/src/service.rs b/tonic-build/src/service.rs index 4829bdb..6569e83 100644 --- a/tonic-build/src/service.rs +++ b/tonic-build/src/service.rs @@ -12,37 +12,34 @@ pub(crate) fn generate(service: &Service, proto_path: &str) -> TokenStream { let generated_trait = generate_trait(service, proto_path, server_trait.clone()); quote! { - use tonic::_codegen::*; - #generated_trait - // TODO: impl debug - #[derive(Clone)] - pub struct #server_make_service { - inner: std::sync::Arc, + #[derive(Clone, Debug)] + pub struct #server_make_service { + inner: Arc, } - // TODO: impl debug - pub struct #server_service { - inner: std::sync::Arc, + #[derive(Clone, Debug)] + pub struct #server_service { + inner: Arc, } - impl #server_make_service { + impl #server_make_service { pub fn new(inner: T) -> Self { - let inner = std::sync::Arc::new(inner); + let inner = Arc::new(inner); Self { inner } } } - impl #server_service { - pub fn new(inner: std::sync::Arc) -> Self { + impl #server_service { + pub fn new(inner: Arc) -> Self { Self { inner } } } - impl Service for #server_make_service { - type Response = #server_service ; - type Error = tonic::error::Never; + impl Service for #server_make_service { + type Response = #server_service; + type Error = Never; type Future = Ready>; fn poll_ready(&mut self, _cx: &mut Context<'_>) -> Poll> { @@ -50,25 +47,26 @@ pub(crate) fn generate(service: &Service, proto_path: &str) -> TokenStream { } fn call(&mut self, _: R) -> Self::Future { - ok(#server_service ::new(self.inner.clone())) + ok(#server_service::new(self.inner.clone())) } } - impl Service> for #server_service { + impl Service> for #server_service { type Response = http::Response; - type Error = tonic::error::Never; + 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 { + fn call(&mut self, req: http::Request) -> Self::Future { let inner = self.inner.clone(); match req.uri().path() { #methods + // TODO: implement grpc unimplemented for server _ => unimplemented!("use grpc unimplemented"), } } @@ -83,7 +81,6 @@ fn generate_trait(service: &Service, proto_path: &str, server_trait: Ident) -> T #[async_trait] pub trait #server_trait : Send + Sync + 'static { #methods - } } } @@ -101,13 +98,13 @@ fn generate_trait_methods(service: &Service, proto_path: &str) -> TokenStream { let method = match (method.client_streaming, method.server_streaming) { (false, false) => { quote! { - async fn #name (&self, request: tonic::Request<#req_message>) + async fn #name(&self, request: tonic::Request<#req_message>) -> Result, tonic::Status>; } } (true, false) => { quote! { - async fn #name (&self, request: tonic::Request>) + async fn #name(&self, request: tonic::Request>) -> Result, tonic::Status>; } } @@ -115,9 +112,9 @@ fn generate_trait_methods(service: &Service, proto_path: &str) -> TokenStream { let stream = quote::format_ident!("{}Stream", method.proto_name); quote! { - type #stream: Stream> + Unpin + Send + 'static; + type #stream: Stream> + Send + 'static; - async fn #name (&self, request: tonic::Request<#req_message>) + async fn #name(&self, request: tonic::Request<#req_message>) -> Result, tonic::Status>; } } @@ -125,9 +122,9 @@ fn generate_trait_methods(service: &Service, proto_path: &str) -> TokenStream { let stream = quote::format_ident!("{}Stream", method.proto_name); quote! { - type #stream: Stream> + Unpin + Send + 'static; + type #stream: Stream> + Send + 'static; - async fn #name (&self, request: tonic::Request>) + async fn #name(&self, request: tonic::Request>) -> Result, tonic::Status>; } } @@ -188,9 +185,9 @@ fn generate_unary( syn::parse_str(&format!("{}::{}", proto_path, method.output_type)).unwrap(); quote! { - struct #service_ident (pub std::sync::Arc); + struct #service_ident(pub Arc); - impl tonic::server::UnaryService<#request> for #service_ident { + impl tonic::server::UnaryService<#request> for #service_ident { type Response = #response; type Future = BoxFuture, tonic::Status>; @@ -231,12 +228,10 @@ fn generate_server_streaming( let response_stream = quote::format_ident!("{}Stream", method.proto_name); - // TODO: parse response stream type, if it is a concrete type then use that - // as the ResponseStream type, if it is a impl Trait then we need to box. quote! { - struct #service_ident (pub std::sync::Arc); + struct #service_ident(pub Arc); - impl tonic::server::ServerStreamingService<#request> for #service_ident { + impl tonic::server::ServerStreamingService<#request> for #service_ident { type Response = #response; type ResponseStream = T::#response_stream; type Future = BoxFuture, tonic::Status>; @@ -277,9 +272,9 @@ fn generate_client_streaming( syn::parse_str(&format!("{}::{}", proto_path, method.output_type)).unwrap(); quote! { - struct #service_ident(pub std::sync::Arc); + struct #service_ident(pub Arc); - impl tonic::server::ClientStreamingService<#request> for #service_ident + impl tonic::server::ClientStreamingService<#request> for #service_ident { type Response = #response; type Future = BoxFuture, tonic::Status>; @@ -322,9 +317,9 @@ fn generate_streaming( let response_stream = quote::format_ident!("{}Stream", method.proto_name); quote! { - struct #service_ident(pub std::sync::Arc); + struct #service_ident(pub Arc); - impl tonic::server::StreamingService<#request> for #service_ident + impl tonic::server::StreamingService<#request> for #service_ident { type Response = #response; type ResponseStream = T::#response_stream; diff --git a/tonic/src/codegen.rs b/tonic/src/codegen.rs new file mode 100644 index 0000000..e5eea9b --- /dev/null +++ b/tonic/src/codegen.rs @@ -0,0 +1,36 @@ +//! Codegen exports used by `tonic-build`. + +pub use async_trait::async_trait; +pub use futures_core::Stream; +pub use futures_util::future::{ok, poll_fn, Ready}; + +pub use http_body::Body as HttpBody; +pub use std::future::Future; +pub use std::pin::Pin; +pub use std::sync::Arc; +pub use std::task::{Context, Poll}; +pub use tower_service::Service; +pub type StdError = Box; +pub use crate::body::Body; + +#[cfg(feature = "transport")] +pub use hyper::Body as HyperBody; + +pub type BoxFuture = self::Pin> + Send + 'static>>; +pub type BoxStream = + self::Pin> + Send + 'static>>; + +pub mod http { + pub use http::*; +} + +#[derive(Debug)] +pub enum Never {} + +impl std::fmt::Display for Never { + fn fmt(&self, _: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match *self {} + } +} + +impl std::error::Error for Never {} diff --git a/tonic/src/error.rs b/tonic/src/error.rs deleted file mode 100644 index 8b3e873..0000000 --- a/tonic/src/error.rs +++ /dev/null @@ -1,14 +0,0 @@ -use std::fmt; - -pub type Error = Box; - -#[derive(Debug)] -pub enum Never {} - -impl fmt::Display for Never { - fn fmt(&self, _: &mut fmt::Formatter<'_>) -> fmt::Result { - match *self {} - } -} - -impl std::error::Error for Never {} diff --git a/tonic/src/lib.rs b/tonic/src/lib.rs index 33d706c..afb1088 100644 --- a/tonic/src/lib.rs +++ b/tonic/src/lib.rs @@ -33,8 +33,6 @@ pub mod body; pub mod client; pub mod codec; -#[doc(hidden)] -pub mod error; pub mod metadata; pub mod server; @@ -56,28 +54,7 @@ pub use status::{Code, Status}; #[doc(inline)] pub use transport::{Channel, Server}; -pub(crate) use error::Error; +pub(crate) type Error = Box; #[doc(hidden)] -pub mod _codegen { - pub use async_trait::async_trait; - pub use futures_core::Stream; - pub use futures_util::future::{ok, poll_fn, Ready}; - pub use http_body::Body as HttpBody; - pub use std::future::Future; - pub use std::pin::Pin; - pub use std::task::{Context, Poll}; - pub use tower_service::Service; - - #[cfg(feature = "transport")] - pub use hyper::Body as HyperBody; - - pub type BoxFuture = - self::Pin> + Send + 'static>>; - pub type BoxStream = - self::Pin> + Send + 'static>>; - - pub mod http { - pub use http::*; - } -} +pub mod codegen; diff --git a/tonic/src/status.rs b/tonic/src/status.rs index 0ccf3c2..e31ebfe 100644 --- a/tonic/src/status.rs +++ b/tonic/src/status.rs @@ -420,7 +420,7 @@ impl From for Code { #[cfg(test)] mod tests { use super::*; - use crate::error::Error; + use crate::Error; #[derive(Debug)] struct Nested(Error);