From a8044bff6694864ee6d5a397d106fb533502f655 Mon Sep 17 00:00:00 2001 From: "NGnius (Graham)" Date: Tue, 1 Aug 2023 11:40:25 -0400 Subject: [PATCH] Misc improvements/fixes for USDPL --- Cargo.lock | 4 +-- nrpc-build/Cargo.toml | 4 +-- nrpc-build/src/service_gen.rs | 68 ++++++++++++++++++++--------------- nrpc-codegen-test/src/main.rs | 16 ++++----- nrpc/Cargo.toml | 7 +++- nrpc/src/lib.rs | 2 +- nrpc/src/service.rs | 34 ++++++++++++------ 7 files changed, 81 insertions(+), 54 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b5d0f5d..d9e4f2d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -417,7 +417,7 @@ checksum = "e5ce46fe64a9d73be07dcbe690a38ce1b293be448fd8ce1e6c1b8062c9f72c6a" [[package]] name = "nrpc" -version = "0.8.0" +version = "0.10.0" dependencies = [ "async-trait", "bytes", @@ -427,7 +427,7 @@ dependencies = [ [[package]] name = "nrpc-build" -version = "0.8.0" +version = "0.10.0" dependencies = [ "nrpc", "prettyplease 0.2.9", diff --git a/nrpc-build/Cargo.toml b/nrpc-build/Cargo.toml index d104aca..f5c2ec2 100644 --- a/nrpc-build/Cargo.toml +++ b/nrpc-build/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "nrpc-build" -version = "0.8.0" +version = "0.10.0" edition = "2021" license = "Apache-2.0" repository = "https://github.com/NGnius/nRPC" @@ -21,4 +21,4 @@ quote = "1.0" syn = "2.0" proc-macro2 = "1.0" -nrpc = { version = "0.8", path = "../nrpc" } +nrpc = { version = "0.10", path = "../nrpc" } diff --git a/nrpc-build/src/service_gen.rs b/nrpc-build/src/service_gen.rs index 153aedb..5b5dd74 100644 --- a/nrpc-build/src/service_gen.rs +++ b/nrpc-build/src/service_gen.rs @@ -47,9 +47,15 @@ impl ProtobufServiceGenerator { } } -fn stream_type(item_type: &syn::Ident) -> proc_macro2::TokenStream { +fn stream_server_type(item_type: &syn::Ident) -> proc_macro2::TokenStream { quote::quote!{ - ::nrpc::ServiceStream<'a, #item_type> + ::nrpc::ServiceServerStream<'a, #item_type> + } +} + +fn stream_client_type(item_type: &syn::Ident) -> proc_macro2::TokenStream { + quote::quote!{ + ::nrpc::ServiceClientStream<'a, #item_type> } } @@ -93,10 +99,10 @@ fn trait_methods_server(descriptors: &Vec) -> proc_macro2:: (false, true) => { // client streaming; 1 -> many //let stream_out_ty = stream_type_static_lifetime(&output_ty); - let stream_out_ty = stream_type(&output_ty); + let stream_out_ty = stream_server_type(&output_ty); gen_methods.push( quote! { - async fn #fn_name<'a>(&mut self, input: #input_ty) -> Result<#stream_out_ty, Box>; + async fn #fn_name<'a: 'b>(&mut self, input: #input_ty) -> Result<#stream_out_ty, Box>; } ); @@ -124,10 +130,10 @@ fn trait_methods_server(descriptors: &Vec) -> proc_macro2:: } (true, false) => { // server streaming; many -> 1 - let stream_in_ty = stream_type(&input_ty); + let stream_in_ty = stream_server_type(&input_ty); gen_methods.push( quote! { - async fn #fn_name<'a>(&mut self, input: #stream_in_ty) -> Result<#output_ty, Box>; + async fn #fn_name<'a: 'b>(&mut self, input: #stream_in_ty) -> Result<#output_ty, Box>; } ); @@ -145,11 +151,11 @@ fn trait_methods_server(descriptors: &Vec) -> proc_macro2:: } (true, true) => { // all streaming; many -> many - let stream_in_ty = stream_type(&input_ty); - let stream_out_ty = stream_type(&output_ty); + let stream_in_ty = stream_server_type(&input_ty); + let stream_out_ty = stream_server_type(&output_ty); gen_methods.push( quote! { - async fn #fn_name<'a>(&mut self, input: #stream_in_ty) -> Result<#stream_out_ty, Box>; + async fn #fn_name<'a: 'b>(&mut self, input: #stream_in_ty) -> Result<#stream_out_ty, Box>; } ); @@ -186,11 +192,11 @@ fn trait_methods_server(descriptors: &Vec) -> proc_macro2:: } }*/ - async fn call<'a>( + async fn call<'a: 'b>( &mut self, method: &str, - mut stream_in: ::nrpc::ServiceStream<'a, ::nrpc::_helpers::bytes::Bytes>, - ) -> Result<::nrpc::ServiceStream<'a, ::nrpc::_helpers::bytes::Bytes>, ::nrpc::ServiceError> { + mut stream_in: ::nrpc::ServiceServerStream<'a, ::nrpc::_helpers::bytes::Bytes>, + ) -> Result<::nrpc::ServiceServerStream<'a, ::nrpc::_helpers::bytes::Bytes>, ::nrpc::ServiceError> { match method { #(#gen_method_match_arms)* _ => Err(::nrpc::ServiceError::MethodNotFound) @@ -232,10 +238,10 @@ fn struct_methods_client( } (false, true) => { // client streaming; 1 -> many - let stream_out_ty = stream_type(&output_ty); + let stream_out_ty = stream_client_type(&output_ty); gen_methods.push( quote! { - pub async fn #fn_name<'a>(&self, input: #input_ty) -> Result<#stream_out_ty, ::nrpc::ServiceError> { + pub async fn #fn_name<'a: 'b>(&self, input: #input_ty) -> Result<#stream_out_ty, ::nrpc::ServiceError> { let mut in_buf = ::nrpc::_helpers::bytes::BytesMut::new(); input.encode(&mut in_buf)?; let in_stream = ::nrpc::OnceStream::once(Ok(in_buf.freeze())); @@ -252,10 +258,10 @@ fn struct_methods_client( } (true, false) => { // server streaming; many -> 1 - let stream_in_ty = stream_type(&input_ty); + let stream_in_ty = stream_client_type(&input_ty); gen_methods.push( quote! { - pub async fn #fn_name<'a>(&self, input: #stream_in_ty) -> Result<#output_ty, ::nrpc::ServiceError> { + pub async fn #fn_name<'a: 'b>(&self, input: #stream_in_ty) -> Result<#output_ty, ::nrpc::ServiceError> { let in_stream = input.map(|item_result| { let mut in_buf = ::nrpc::_helpers::bytes::BytesMut::new(); item_result.and_then(|item| item.encode(&mut in_buf) @@ -276,11 +282,11 @@ fn struct_methods_client( } (true, true) => { // all streaming; many -> many - let stream_in_ty = stream_type(&input_ty); - let stream_out_ty = stream_type(&output_ty); + let stream_in_ty = stream_client_type(&input_ty); + let stream_out_ty = stream_client_type(&output_ty); gen_methods.push( quote! { - pub async fn #fn_name<'a>(&self, input: #stream_in_ty) -> Result<#stream_out_ty, ::nrpc::ServiceError> { + pub async fn #fn_name<'a: 'b>(&self, input: #stream_in_ty) -> Result<#stream_out_ty, ::nrpc::ServiceError> { let in_stream = input.map(|item_result| { let mut in_buf = ::nrpc::_helpers::bytes::BytesMut::new(); item_result.and_then(|item| item.encode(&mut in_buf) @@ -342,33 +348,35 @@ impl ServiceGenerator for ProtobufServiceGenerator { use ::nrpc::_helpers::futures::StreamExt; #[async_trait] - pub trait #service_trait_name: Send { + pub trait #service_trait_name<'b>: Send { #service_trait_methods } - pub struct #service_struct_name { + pub struct #service_struct_name<'b, T: #service_trait_name<'b>> { inner: T, + _idc: std::marker::PhantomData<&'b ()>, } - impl #service_struct_name { + impl <'b, T: #service_trait_name<'b>> #service_struct_name<'b, T> { pub fn new(inner: T) -> Self { Self { inner, + _idc: Default::default(), } } } #[async_trait] - impl ::nrpc::ServerService for #service_struct_name { + impl<'b, T: #service_trait_name<'b>> ::nrpc::ServerService<'b> for #service_struct_name<'b, T> { fn descriptor(&self) -> &'static str { #descriptor_str } - async fn call<'a>( + async fn call<'a: 'b>( &mut self, method: &str, - input: ::nrpc::ServiceStream<'a, ::nrpc::_helpers::bytes::Bytes>, - ) -> Result<::nrpc::ServiceStream<'a, ::nrpc::_helpers::bytes::Bytes>, ::nrpc::ServiceError> { + input: ::nrpc::ServiceServerStream<'a, ::nrpc::_helpers::bytes::Bytes>, + ) -> Result<::nrpc::ServiceServerStream<'a, ::nrpc::_helpers::bytes::Bytes>, ::nrpc::ServiceError> { self.inner.call(method, input).await } } @@ -400,20 +408,22 @@ impl ServiceGenerator for ProtobufServiceGenerator { use ::nrpc::_helpers::futures::StreamExt; //#[derive(core::any::Any)] - pub struct #service_struct_name { + pub struct #service_struct_name<'b, T: ::nrpc::ClientHandler<'b>> { inner: T, + _idc: std::marker::PhantomData<&'b ()>, } - impl ::nrpc::ClientService for #service_struct_name { + impl <'b, T: ::nrpc::ClientHandler<'b>> ::nrpc::ClientService for #service_struct_name<'b, T> { fn descriptor(&self) -> &'static str { #descriptor_str } } - impl #service_struct_name { + impl <'b, T: ::nrpc::ClientHandler<'b>> #service_struct_name<'b, T> { pub fn new(inner: T) -> Self { Self { inner, + _idc: Default::default(), } } diff --git a/nrpc-codegen-test/src/main.rs b/nrpc-codegen-test/src/main.rs index 3141a94..ea98e76 100644 --- a/nrpc-codegen-test/src/main.rs +++ b/nrpc-codegen-test/src/main.rs @@ -131,7 +131,7 @@ async fn main() { struct GreeterService; #[async_trait::async_trait] -impl helloworld::IGreeter for GreeterService { +impl helloworld::IGreeter<'_> for GreeterService { async fn say_hello( &mut self, input: helloworld::HelloRequest, @@ -147,7 +147,7 @@ impl helloworld::IGreeter for GreeterService { &mut self, input: helloworld::HelloRequest, ) -> Result< - ::nrpc::ServiceStream<'a, helloworld::HelloReply>, + ::nrpc::ServiceServerStream<'a, helloworld::HelloReply>, Box, > { let result = helloworld::HelloReply { @@ -159,7 +159,7 @@ impl helloworld::IGreeter for GreeterService { async fn say_hello_many_to_one<'a>( &mut self, - mut input: ::nrpc::ServiceStream<'a, helloworld::HelloRequest>, + mut input: ::nrpc::ServiceServerStream<'a, helloworld::HelloRequest>, ) -> Result>{ let mut message = "Hello ".to_string(); while let Some(item_result) = input.next().await { @@ -173,9 +173,9 @@ impl helloworld::IGreeter for GreeterService { async fn say_hello_many_to_many<'a>( &mut self, - input: ::nrpc::ServiceStream<'a, helloworld::HelloRequest>, + input: ::nrpc::ServiceServerStream<'a, helloworld::HelloRequest>, ) -> Result< - ::nrpc::ServiceStream<'a, helloworld::HelloReply>, + ::nrpc::ServiceServerStream<'a, helloworld::HelloReply>, Box, >{ Ok(Box::new(input.map(|item_result| item_result.map(|input| { @@ -191,7 +191,7 @@ impl helloworld::IGreeter for GreeterService { struct ClientHandler; #[async_trait::async_trait] -impl nrpc::ClientHandler for ClientHandler { +impl nrpc::ClientHandler<'_> for ClientHandler { /*async fn call( &mut self, package: &str, @@ -216,8 +216,8 @@ impl nrpc::ClientHandler for ClientHandler { package: &str, service: &str, method: &str, - input: ::nrpc::ServiceStream<'a, ::nrpc::_helpers::bytes::Bytes>, - ) -> Result<::nrpc::ServiceStream<'a, ::nrpc::_helpers::bytes::Bytes>, ServiceError> { + input: ::nrpc::ServiceClientStream<'a, ::nrpc::_helpers::bytes::Bytes>, + ) -> Result<::nrpc::ServiceClientStream<'a, ::nrpc::_helpers::bytes::Bytes>, ServiceError> { println!( "call {}.{}/{} with data stream", package, service, method diff --git a/nrpc/Cargo.toml b/nrpc/Cargo.toml index 235fe72..118cc63 100644 --- a/nrpc/Cargo.toml +++ b/nrpc/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "nrpc" -version = "0.8.0" +version = "0.10.0" edition = "2021" license = "Apache-2.0" repository = "https://github.com/NGnius/nRPC" @@ -12,3 +12,8 @@ prost = "0.11" bytes = "1" async-trait = "0.1" futures = "0.3" + +[features] +default = ["client-send", "server-send"] +client-send = [] +server-send = [] diff --git a/nrpc/src/lib.rs b/nrpc/src/lib.rs index 746eda1..b5602b6 100644 --- a/nrpc/src/lib.rs +++ b/nrpc/src/lib.rs @@ -1,7 +1,7 @@ mod service; mod stream_utils; -pub use service::{ClientHandler, ClientService, ServerService, ServiceError, ServiceStream}; +pub use service::{ClientHandler, ClientService, ServerService, ServiceError, ServiceClientStream, ServiceServerStream}; pub use stream_utils::{EmptyStream, OnceStream, VecStream}; diff --git a/nrpc/src/service.rs b/nrpc/src/service.rs index 59fbc48..a3e7e10 100644 --- a/nrpc/src/service.rs +++ b/nrpc/src/service.rs @@ -1,28 +1,40 @@ use futures::Stream; use core::marker::Unpin; -pub type ServiceStream<'a, T> = Box> + Unpin + Send + 'a>; +#[cfg(feature = "client-send")] +pub type ServiceClientStream<'a, T> = Box> + Unpin + Send + 'a>; -#[async_trait::async_trait] -pub trait ServerService { +#[cfg(not(feature = "client-send"))] +pub type ServiceClientStream<'a, T> = Box> + Unpin + 'a>; + +#[cfg(feature = "server-send")] +pub type ServiceServerStream<'a, T> = Box> + Unpin + Send + 'a>; + +#[cfg(not(feature = "server-send"))] +pub type ServiceServerStream<'a, T> = Box> + Unpin + 'a>; + +#[cfg_attr(feature = "server-send", async_trait::async_trait)] +#[cfg_attr(not(feature = "server-send"), async_trait::async_trait(?Send))] +pub trait ServerService<'b> { fn descriptor(&self) -> &'static str; - async fn call<'a>( + async fn call<'a: 'b>( &mut self, method: &str, - input: ServiceStream<'a, bytes::Bytes>, - ) -> Result, ServiceError>; + input: ServiceServerStream<'a, bytes::Bytes>, + ) -> Result, ServiceError>; } -#[async_trait::async_trait] -pub trait ClientHandler { - async fn call<'a>( +#[cfg_attr(feature = "client-send", async_trait::async_trait)] +#[cfg_attr(not(feature = "client-send"), async_trait::async_trait(?Send))] +pub trait ClientHandler<'b> { + async fn call<'a: 'b>( &self, package: &str, service: &str, method: &str, - input: ServiceStream<'a, bytes::Bytes>, - ) -> Result, ServiceError>; + input: ServiceClientStream<'a, bytes::Bytes>, + ) -> Result, ServiceError>; } pub trait ClientService {