diff --git a/service-sdk-macros/Cargo.toml b/service-sdk-macros/Cargo.toml index 45c0444..03b1027 100644 --- a/service-sdk-macros/Cargo.toml +++ b/service-sdk-macros/Cargo.toml @@ -20,3 +20,5 @@ proc-macro = true quote = "*" proc-macro2 = "*" + +syn = { version = "*", features = ["full"] } diff --git a/service-sdk-macros/src/lib.rs b/service-sdk-macros/src/lib.rs index ae9e187..a80f887 100644 --- a/service-sdk-macros/src/lib.rs +++ b/service-sdk-macros/src/lib.rs @@ -296,6 +296,33 @@ pub fn use_signal_r_subscriber(_input: TokenStream) -> TokenStream { .into() } +use quote::quote; +use syn::{ + parse::{Parse, ParseStream}, + parse_macro_input, + Ident, Path, Result, Token, Type, +}; + +struct GenerateGrpcServiceArgs { + service_ident: Ident, + app_ty: Type, + server_path: Path, +} + +impl Parse for GenerateGrpcServiceArgs { + fn parse(input: ParseStream) -> Result { + let service_ident: Ident = input.parse()?; + input.parse::()?; + + let app_ty: Type = input.parse()?; + input.parse::()?; + + let server_path: Path = input.parse()?; + + Ok(Self { service_ident, app_ty, server_path }) + } +} + #[proc_macro] pub fn generate_grpc_service(input: TokenStream) -> TokenStream { let input: proc_macro2::TokenStream = input.into(); @@ -316,3 +343,31 @@ pub fn generate_grpc_service(input: TokenStream) -> TokenStream { } .into() } + +#[proc_macro] +pub fn generate_named_grpc_service(input: TokenStream) -> TokenStream { + let GenerateGrpcServiceArgs { service_ident, app_ty, server_path } = parse_macro_input!(input as GenerateGrpcServiceArgs); + + let expanded = quote! { + #[derive(Clone)] + pub struct #service_ident { + pub app_context: ::std::sync::Arc<#app_ty>, + } + + impl #service_ident { + pub fn new(app_context: ::std::sync::Arc<#app_ty>) -> Self { + Self { app_context } + } + } + + impl service_sdk::IntoGrpcServer for #service_ident { + type GrpcServer = #server_path; + + fn into_grpc_server(self) -> Self::GrpcServer { + #server_path::new(self) + } + } + }; + + expanded.into() +} diff --git a/service-sdk/src/builders/grpc_server_builder.rs b/service-sdk/src/builders/grpc_server_builder.rs index 27b3032..0326933 100644 --- a/service-sdk/src/builders/grpc_server_builder.rs +++ b/service-sdk/src/builders/grpc_server_builder.rs @@ -14,6 +14,8 @@ use my_logger::LogEventCtx; use crate::GrpcMetricsMiddlewareLayer; +use crate::IntoGrpcServer; + const DEFAULT_GRPC_PORT: u16 = 8888; pub struct GrpcServerBuilder { server: Option< @@ -56,6 +58,14 @@ impl GrpcServerBuilder { self.listen_address = Some(SocketAddr::new(ip, port)); } + pub fn add_service(&mut self, svc: S) + where + S: IntoGrpcServer, + >>::Future: Send + 'static, + { + self.add_grpc_service(svc.into_grpc_server()); + } + pub fn add_grpc_service(&mut self, svc: S) where S: Service< diff --git a/service-sdk/src/common/into_grpc_server.rs b/service-sdk/src/common/into_grpc_server.rs new file mode 100644 index 0000000..debb849 --- /dev/null +++ b/service-sdk/src/common/into_grpc_server.rs @@ -0,0 +1,21 @@ +use std::convert::Infallible; + +use my_grpc_extensions::tonic::{ + body::Body, + codegen::{http::Request, Service}, + server::NamedService, +}; + +pub trait IntoGrpcServer { + type GrpcServer: Service< + Request, + Response = my_grpc_extensions::hyper::Response, + Error = Infallible, + > + NamedService + + Clone + + Send + + Sync + + 'static; + + fn into_grpc_server(self) -> Self::GrpcServer; +} diff --git a/service-sdk/src/common/mod.rs b/service-sdk/src/common/mod.rs index ed46629..a66fb47 100644 --- a/service-sdk/src/common/mod.rs +++ b/service-sdk/src/common/mod.rs @@ -1,2 +1,7 @@ mod service_info; pub use service_info::*; + +#[cfg(feature = "grpc")] +mod into_grpc_server; +#[cfg(feature = "grpc")] +pub use into_grpc_server::*; \ No newline at end of file