Skip to main content

synapse_codegen/
client_gen.rs

1//! Client stub generation
2
3use crate::ServiceDef;
4use anyhow::Result;
5use proc_macro2::TokenStream;
6use quote::{format_ident, quote};
7
8/// Generate client stub for a service
9///
10/// Generated clients accept a SynClient (unified connection pool) instead of creating their own.
11/// This allows efficient connection reuse across all service clients.
12///
13/// Example output:
14/// ```text
15/// pub struct UserServiceClient {
16///     client: synapse_sdk::SynClient,
17/// }
18///
19/// impl UserServiceClient {
20///     pub fn new(client: synapse_sdk::SynClient) -> Self { ... }
21///     pub async fn get_user(&self, request: GetUserRequest) -> Result<GetUserResponse> { ... }
22/// }
23/// ```
24pub fn generate_client_stub(service: &ServiceDef) -> Result<TokenStream> {
25    let client_name = format_ident!("{}Client", service.service_name);
26    let package = &service.package;
27
28    let interface_id = service.interface_id_expr();
29
30    // Generate method stubs
31    let methods: Vec<TokenStream> = service
32        .methods
33        .iter()
34        .map(|method| {
35            let method_name = format_ident!("{}", method.method_name_snake());
36            let method_id = method.method_id_expr();
37            let input_type = method.input_type_path(package);
38            let output_type = method.output_type_path(package);
39
40            let comment = method.comment.as_ref().map(|c| {
41                let doc = format!(" {}", c);
42                quote! { #[doc = #doc] }
43            });
44
45            quote! {
46                #comment
47                pub async fn #method_name(&self, request: #input_type) -> anyhow::Result<#output_type> {
48                    self.client.call_proto(#interface_id, #method_id, &request).await
49                }
50            }
51        })
52        .collect();
53
54    Ok(quote! {
55        /// Generated client for #client_name
56        ///
57        /// Uses the shared SynClient connection pool for efficient communication.
58        #[derive(Clone)]
59        pub struct #client_name {
60            client: synapse_sdk::SynClient,
61        }
62
63        impl #client_name {
64            /// Create a new client using a SynClient connection pool
65            pub fn new(client: synapse_sdk::SynClient) -> Self {
66                Self { client }
67            }
68
69            #(#methods)*
70        }
71    })
72}