use crate::deserialize::util::{make_build_fn_name, make_build_pair}; use crate::spec::leaf_struct_spec::{LeafStructBuildSpec, LeafStructMemberKind}; use proc_macro2::TokenStream; use quote::{format_ident, quote}; pub fn make_leaf_struct_build_fn(build_spec: &LeafStructBuildSpec) -> TokenStream { let build_fn_ident = format_ident!("{}", make_build_fn_name(build_spec.build())); let pair_ident = format_ident!("{}", make_build_pair(build_spec.build())); let return_type_ident = format_ident!("{}", build_spec.build()); let child_builders = build_spec .members() .map(|member| { let child_ident = format_ident!("{}", member.name()); match member.kind() { LeafStructMemberKind::String => { quote! { let #child_ident = #pair_ident.as_str() } } LeafStructMemberKind::FileId => { quote! { let #child_ident = file_id } } LeafStructMemberKind::Range => { quote! { let #child_ident = { let as_span = #pair_ident.as_span(); Range { start: as_span.start(), end: as_span.end() } } } } } }) .collect::>(); let child_args = build_spec .members() .map(|member| format_ident!("{}", member.name())) .collect::>(); quote! { fn #build_fn_ident(file_id: usize, #pair_ident: Pair) -> #return_type_ident { #(#child_builders;)* #return_type_ident::new( #(#child_args,)* ) } } }