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.
This commit is contained in:
+33
-27
@@ -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<T> {
|
||||
inner: tonic::client::Grpc<T>,
|
||||
}
|
||||
/// Generated server implementations.
|
||||
pub mod #client_mod {
|
||||
#![allow(unused_variables, dead_code, missing_docs)]
|
||||
use tonic::codegen::*;
|
||||
|
||||
#connect
|
||||
|
||||
impl<T> #service_ident<T>
|
||||
where T: tonic::client::GrpcService<tonic::body::BoxBody>,
|
||||
T::ResponseBody: Body + HttpBody + Send + 'static,
|
||||
T::Error: Into<StdError>,
|
||||
<T::ResponseBody as HttpBody>::Error: Into<StdError> + Send,
|
||||
{
|
||||
pub fn new(inner: T) -> Self {
|
||||
let inner = tonic::client::Grpc::new(inner);
|
||||
Self { inner }
|
||||
#service_doc
|
||||
pub struct #service_ident<T> {
|
||||
inner: tonic::client::Grpc<T>,
|
||||
}
|
||||
|
||||
/// 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<T> #service_ident<T>
|
||||
where T: tonic::client::GrpcService<tonic::body::BoxBody>,
|
||||
T::ResponseBody: Body + HttpBody + Send + 'static,
|
||||
T::Error: Into<StdError>,
|
||||
<T::ResponseBody as HttpBody>::Error: Into<StdError> + 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<T: Clone> Clone for #service_ident<T> {
|
||||
fn clone(&self) -> Self {
|
||||
Self {
|
||||
inner: self.inner.clone(),
|
||||
impl<T: Clone> Clone for #service_ident<T> {
|
||||
fn clone(&self) -> Self {
|
||||
Self {
|
||||
inner: self.inner.clone(),
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+2
-14
@@ -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);
|
||||
|
||||
+48
-41
@@ -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<T: #server_trait> {
|
||||
inner: Arc<T>,
|
||||
}
|
||||
#generated_trait
|
||||
|
||||
impl<T: #server_trait> #server_service<T> {
|
||||
pub fn new(inner: T) -> Self {
|
||||
let inner = Arc::new(inner);
|
||||
Self { inner }
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: #server_trait> Service<http::Request<HyperBody>> for #server_service<T> {
|
||||
type Response = http::Response<tonic::body::BoxBody>;
|
||||
type Error = Never;
|
||||
type Future = BoxFuture<Self::Response, Self::Error>;
|
||||
|
||||
fn poll_ready(&mut self, _cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
|
||||
Poll::Ready(Ok(()))
|
||||
#service_doc
|
||||
#[derive(Debug)]
|
||||
#[doc(hidden)]
|
||||
pub struct #server_service<T: #server_trait> {
|
||||
inner: Arc<T>,
|
||||
}
|
||||
|
||||
fn call(&mut self, req: http::Request<HyperBody>) -> 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<T: #server_trait> #server_service<T> {
|
||||
pub fn new(inner: T) -> Self {
|
||||
let inner = Arc::new(inner);
|
||||
Self { inner }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: #server_trait> Clone for #server_service<T> {
|
||||
fn clone(&self) -> Self {
|
||||
let inner = self.inner.clone();
|
||||
Self { inner }
|
||||
impl<T: #server_trait> Service<http::Request<HyperBody>> for #server_service<T> {
|
||||
type Response = http::Response<tonic::body::BoxBody>;
|
||||
type Error = Never;
|
||||
type Future = BoxFuture<Self::Response, Self::Error>;
|
||||
|
||||
fn poll_ready(&mut self, _cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
|
||||
Poll::Ready(Ok(()))
|
||||
}
|
||||
|
||||
fn call(&mut self, req: http::Request<HyperBody>) -> 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<T: #server_trait> Clone for #server_service<T> {
|
||||
fn clone(&self) -> Self {
|
||||
let inner = self.inner.clone();
|
||||
Self { inner }
|
||||
}
|
||||
}
|
||||
|
||||
#transport
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user