use convert_case::{Case, Casing};
use quote::format_ident;
pub(crate) fn collect_generated_type_names(
struct_name: &str,
declarations: &[prompt_templates::VarDecl],
) -> Vec<syn::Ident> {
let mut names = vec![format_ident!("{}", struct_name)];
for decl in declarations {
collect_nested_names(struct_name, &decl.name, &decl.var_type, &mut names);
}
names
}
fn collect_nested_names(
parent: &str,
field: &str,
ty: &prompt_templates::VarType,
names: &mut Vec<syn::Ident>,
) {
use prompt_templates::VarType;
match ty {
VarType::List(fields)
if !fields.is_empty() && (fields.len() != 1 || !fields[0].name.is_empty()) =>
{
let pascal = field.to_case(Case::Pascal);
let item_name = format!("{parent}{pascal}Item");
names.push(format_ident!("{}", item_name));
for f in fields {
collect_nested_names(&item_name, &f.name, &f.var_type, names);
}
}
VarType::Struct(fields) if !fields.is_empty() => {
let pascal = field.to_case(Case::Pascal);
let nested_name = format!("{parent}{pascal}");
names.push(format_ident!("{}", nested_name));
for f in fields {
collect_nested_names(&nested_name, &f.name, &f.var_type, names);
}
}
VarType::Option(inner) => {
collect_nested_names(parent, field, inner, names);
}
_ => {}
}
}