use cratestack_core::{Field, Model};
use quote::quote;
use crate::shared::{ident, pluralize, to_snake_case};
pub(super) fn build_client_struct(
package: &str,
models_with_pk: &[(&Model, &Field)],
) -> proc_macro2::TokenStream {
let model_accessors = models_with_pk
.iter()
.map(|(model, _pk)| {
let accessor_ident = ident(&pluralize(&to_snake_case(&model.name)));
let api_ident = ident(&format!("{}GrpcApi", model.name));
quote! {
pub fn #accessor_ident(&self) -> #api_ident<T> {
#api_ident { grpc: self.grpc.clone() }
}
}
})
.collect::<Vec<_>>();
quote! {
#[derive(Debug, Clone)]
pub struct Client<T = ::cratestack::grpc::tonic::transport::Channel> {
grpc: ::cratestack::client_rust::grpc::CratestackGrpcClient<T>,
}
impl Client<::cratestack::grpc::tonic::transport::Channel> {
pub async fn connect<D>(
dst: D,
) -> ::core::result::Result<Self, ::cratestack::grpc::tonic::transport::Error>
where
D: ::core::convert::TryInto<::cratestack::grpc::tonic::transport::Endpoint>,
D::Error: ::core::convert::Into<::cratestack::grpc::tonic::codegen::StdError>,
{
let conn = ::cratestack::grpc::tonic::transport::Endpoint::new(dst)?
.connect()
.await?;
Ok(Self::new(conn))
}
}
impl<T> Client<T> {
pub fn new(inner: T) -> Self {
Self {
grpc: ::cratestack::client_rust::grpc::CratestackGrpcClient::new(inner, #package)
.with_schema_sha(super::SCHEMA_SHA256),
}
}
pub fn with_request_authorizer(
mut self,
request_authorizer: ::std::sync::Arc<dyn ::cratestack::client_rust::RequestAuthorizer>,
) -> Self {
self.grpc = self.grpc.with_request_authorizer(request_authorizer);
self
}
}
impl<T> Client<T>
where
T: ::core::clone::Clone,
{
#(#model_accessors)*
}
}
}