use std::collections::BTreeMap;
use quote::quote;
use crate::shared::ident;
use super::rpc_inputs::lock_number;
pub(super) fn render_rpc_list_input(
model_name: &str,
numbers: &BTreeMap<String, i32>,
) -> Result<proc_macro2::TokenStream, String> {
let message_name = format!("{model_name}RpcListInput");
let ident_tok = ident(&message_name);
let limit = lock_number(numbers, &message_name, "limit")?;
let offset = lock_number(numbers, &message_name, "offset")?;
let fields = lock_number(numbers, &message_name, "fields")?;
let include = lock_number(numbers, &message_name, "include")?;
let include_fields = lock_number(numbers, &message_name, "include_fields")?;
let sort = lock_number(numbers, &message_name, "sort")?;
let where_expr = lock_number(numbers, &message_name, "where_expr")?;
let or_field = lock_number(numbers, &message_name, "or")?;
let filters = lock_number(numbers, &message_name, "filters")?;
Ok(quote! {
#[derive(Clone, PartialEq, ::cratestack::grpc::prost::Message)]
pub struct #ident_tok {
#[prost(int64, optional, tag = #limit)]
pub limit: Option<i64>,
#[prost(int64, optional, tag = #offset)]
pub offset: Option<i64>,
#[prost(string, repeated, tag = #fields)]
pub fields: Vec<String>,
#[prost(string, repeated, tag = #include)]
pub include: Vec<String>,
#[prost(map = "string, message", tag = #include_fields)]
pub include_fields: ::std::collections::HashMap<String, StringList>,
#[prost(string, optional, tag = #sort)]
pub sort: Option<String>,
#[prost(string, optional, tag = #where_expr)]
pub where_expr: Option<String>,
#[prost(string, optional, tag = #or_field)]
pub or: Option<String>,
#[prost(message, repeated, tag = #filters)]
pub filters: Vec<RpcListPredicate>,
}
impl #ident_tok {
pub(super) fn into_domain(self) -> ::cratestack::rpc::RpcListInput {
::cratestack::rpc::RpcListInput {
limit: self.limit,
offset: self.offset,
fields: if self.fields.is_empty() { None } else { Some(self.fields) },
include: if self.include.is_empty() { None } else { Some(self.include) },
include_fields: self.include_fields
.into_iter()
.map(|(key, value)| (key, value.values))
.collect(),
sort: self.sort,
where_expr: self.where_expr,
or: self.or,
filters: self.filters
.into_iter()
.map(|predicate| ::cratestack::rpc::RpcListPredicate {
key: predicate.key,
value: predicate.value,
})
.collect(),
}
}
}
})
}
pub(super) fn render_page_of(
model_name: &str,
numbers: &BTreeMap<String, i32>,
) -> Result<proc_macro2::TokenStream, String> {
let message_name = format!("PageOf{model_name}");
let ident_tok = ident(&message_name);
let items = lock_number(numbers, &message_name, "items")?;
let total_count = lock_number(numbers, &message_name, "total_count")?;
let page_info = lock_number(numbers, &message_name, "page_info")?;
let model_ident = ident(model_name);
Ok(quote! {
#[derive(Clone, PartialEq, ::cratestack::grpc::prost::Message)]
pub struct #ident_tok {
#[prost(message, repeated, tag = #items)]
pub items: Vec<#model_ident>,
#[prost(int64, optional, tag = #total_count)]
pub total_count: Option<i64>,
#[prost(message, optional, tag = #page_info)]
pub page_info: Option<PageInfo>,
}
impl ::core::convert::From<&::cratestack::Page<super::super::#model_ident>> for #ident_tok {
fn from(value: &::cratestack::Page<super::super::#model_ident>) -> Self {
Self {
items: value.items.iter().map(#model_ident::from).collect(),
total_count: value.total_count,
page_info: Some(PageInfo::from(&value.page_info)),
}
}
}
})
}