Remove duplicate conflicting module naming by shifting around rexports

This commit is contained in:
NGnius (Graham) 2023-04-16 18:29:51 -04:00
parent eddfa40933
commit 7d326ea183
4 changed files with 63 additions and 11 deletions

2
Cargo.lock generated
View file

@ -290,7 +290,7 @@ dependencies = [
[[package]] [[package]]
name = "nrpc-build" name = "nrpc-build"
version = "0.4.0" version = "0.5.0"
dependencies = [ dependencies = [
"nrpc", "nrpc",
"prettyplease 0.2.4", "prettyplease 0.2.4",

View file

@ -1,6 +1,6 @@
[package] [package]
name = "nrpc-build" name = "nrpc-build"
version = "0.4.0" version = "0.5.0"
edition = "2021" edition = "2021"
license = "Apache-2.0" license = "Apache-2.0"
repository = "https://github.com/NGnius/nRPC" repository = "https://github.com/NGnius/nRPC"

View file

@ -4,6 +4,8 @@ use quote::quote;
pub(crate) struct ProtobufServiceGenerator { pub(crate) struct ProtobufServiceGenerator {
generate_server: bool, generate_server: bool,
generate_client: bool, generate_client: bool,
client_reexports: Vec<proc_macro2::TokenStream>,
server_reexports: Vec<proc_macro2::TokenStream>,
} }
impl ProtobufServiceGenerator { impl ProtobufServiceGenerator {
@ -11,6 +13,8 @@ impl ProtobufServiceGenerator {
Self { Self {
generate_server: true, generate_server: true,
generate_client: true, generate_client: true,
client_reexports: Vec::new(),
server_reexports: Vec::new(),
} }
} }
@ -18,6 +22,8 @@ impl ProtobufServiceGenerator {
Self { Self {
generate_server: false, generate_server: false,
generate_client: true, generate_client: true,
client_reexports: Vec::new(),
server_reexports: Vec::new(),
} }
} }
@ -25,6 +31,8 @@ impl ProtobufServiceGenerator {
Self { Self {
generate_server: true, generate_server: true,
generate_client: false, generate_client: false,
client_reexports: Vec::new(),
server_reexports: Vec::new(),
} }
} }
} }
@ -125,6 +133,8 @@ impl ServiceGenerator for ProtobufServiceGenerator {
let service_trait_methods = trait_methods_server(&service.methods); let service_trait_methods = trait_methods_server(&service.methods);
let service_struct_name = quote::format_ident!("{}ServiceImpl", service.name); let service_struct_name = quote::format_ident!("{}ServiceImpl", service.name);
let descriptor_str = format!("{}.{}", service.package, service.name); let descriptor_str = format!("{}.{}", service.package, service.name);
let service_struct_rename = quote::format_ident!("{}Server", service.name);
let service_trait_rename = quote::format_ident!("I{}", service.name);
let gen_service = quote! { let gen_service = quote! {
mod #service_mod_name { mod #service_mod_name {
use super::*; use super::*;
@ -159,10 +169,14 @@ impl ServiceGenerator for ProtobufServiceGenerator {
} }
} }
} }
pub mod server { pub use #service_mod_name::{
pub use super::#service_mod_name::{#service_struct_name, #service_trait_name}; #service_struct_name as #service_struct_rename,
} #service_trait_name as #service_trait_rename,
};
}; };
self.server_reexports.push(quote! {
pub use super::#service_mod_name::{#service_struct_name, #service_trait_name};
});
let gen_code: syn::File = syn::parse2(gen_service).expect("invalid tokenstream"); let gen_code: syn::File = syn::parse2(gen_service).expect("invalid tokenstream");
let code_str = prettyplease::unparse(&gen_code); let code_str = prettyplease::unparse(&gen_code);
buf.push_str(&code_str); buf.push_str(&code_str);
@ -172,6 +186,7 @@ impl ServiceGenerator for ProtobufServiceGenerator {
let service_methods = struct_methods_client(&service.name, &service.methods); let service_methods = struct_methods_client(&service.name, &service.methods);
let service_struct_name = quote::format_ident!("{}Service", service.name); let service_struct_name = quote::format_ident!("{}Service", service.name);
let descriptor_str = format!("{}.{}", service.package, service.name); let descriptor_str = format!("{}.{}", service.package, service.name);
let service_rename = quote::format_ident!("{}Client", service.name);
let gen_client = quote! { let gen_client = quote! {
mod #service_mod_name { mod #service_mod_name {
use super::*; use super::*;
@ -198,13 +213,50 @@ impl ServiceGenerator for ProtobufServiceGenerator {
#service_methods #service_methods
} }
} }
pub mod client { pub use #service_mod_name::#service_struct_name as #service_rename;
pub use super::#service_mod_name::#service_struct_name;
}
}; };
self.client_reexports.push(quote! {
pub use super::#service_mod_name::#service_struct_name;
});
let gen_code: syn::File = syn::parse2(gen_client).expect("invalid tokenstream"); let gen_code: syn::File = syn::parse2(gen_client).expect("invalid tokenstream");
let code_str = prettyplease::unparse(&gen_code); let code_str = prettyplease::unparse(&gen_code);
buf.push_str(&code_str); buf.push_str(&code_str);
} }
} }
fn finalize_package(&mut self, _package: &str, buf: &mut String) {
self.finalize(buf);
}
fn finalize(&mut self, buf: &mut String) {
let mut client_tokens = quote!{};
let mut server_tokens = quote!{};
if self.generate_client {
let exports = &self.client_reexports;
client_tokens = quote! {
pub mod client {
#(#exports)*
}
};
}
if self.generate_server {
let exports = &self.server_reexports;
server_tokens = quote! {
pub mod server {
#(#exports)*
}
};
}
let gen_code = quote! {
#client_tokens
#server_tokens
pub mod finally {}
};
let gen_code: syn::File = syn::parse2(gen_code).expect("invalid tokenstream");
let code_str = prettyplease::unparse(&gen_code);
buf.push_str(&code_str);
}
} }

View file

@ -16,7 +16,7 @@ async fn main() {
message: "Hello World".into(), message: "Hello World".into(),
}; };
// server // server
let mut service_impl = helloworld::server::GreeterServiceImpl::new(GreeterService); let mut service_impl = helloworld::GreeterServer::new(GreeterService);
let mut input_buf = bytes::BytesMut::new(); let mut input_buf = bytes::BytesMut::new();
let mut output_buf = bytes::BytesMut::new(); let mut output_buf = bytes::BytesMut::new();
req.encode(&mut input_buf).unwrap(); req.encode(&mut input_buf).unwrap();
@ -25,7 +25,7 @@ async fn main() {
assert_eq!(resp, actual_resp); assert_eq!(resp, actual_resp);
// client // client
let mut client_impl = helloworld::client::GreeterService::new(ClientHandler); let mut client_impl = helloworld::GreeterClient::new(ClientHandler);
let resp = client_impl.say_hello(req).await.unwrap(); let resp = client_impl.say_hello(req).await.unwrap();
assert_eq!(resp, actual_resp); assert_eq!(resp, actual_resp);
} }
@ -33,7 +33,7 @@ async fn main() {
struct GreeterService; struct GreeterService;
#[async_trait::async_trait] #[async_trait::async_trait]
impl helloworld::server::GreeterService for GreeterService { impl helloworld::IGreeter for GreeterService {
async fn say_hello(&mut self, input: helloworld::HelloRequest) -> Result<helloworld::HelloReply, Box<dyn Error>> { async fn say_hello(&mut self, input: helloworld::HelloRequest) -> Result<helloworld::HelloReply, Box<dyn Error>> {
let result = helloworld::HelloReply { let result = helloworld::HelloReply {
message: format!("Hello {}", input.name), message: format!("Hello {}", input.name),