Once again separating different code into clearer modules to improve readability. The macro attribute parsing that generates a Group
will also live in this new module.
XGNME3WRU3MJDTFHUFJYARLVXWBZIH5ODBOIIFTXHNCBTZQH2R7QC
D652S2N3MHR7NJWSJIT7DUH5TPEFF6YII7EGV4C7IYWARXLMGAWQC
O77KA6C4UJGZXVGPEA7WCRQH6XYQJPWETSPDXI3VOKOSRQND7JEQC
UOMQT7LTURIIWHZT2ZHLCJG6XESYTN26EJC7IHRFR4PYJ355PNYAC
5TEX4MNUC4LDDRMNEOVCFNUUEZAGUXMKO3OIEQFXWRQKXSHY2NRQC
K4XW4OBW5VWRCQZJNVV624E25SKRJPZ5WUXWVYHP6U7T7NPJFMFQC
56F2YE6HUZ76U4QBPUDJ2VQLJ75TQYNTVQIOX4QBOZ2H6GJKRGUQC
use crate::group::Group;
use heck::{ToKebabCase, ToSnakeCase};
use quote::{format_ident, quote};
pub fn derive_enum(
group: Group,
ident: syn::Ident,
enum_data: syn::DataEnum,
) -> proc_macro2::TokenStream {
let mut idents = Vec::with_capacity(enum_data.variants.len());
let mut messages = Vec::with_capacity(enum_data.variants.len());
for variant in enum_data.variants {
let kebab_case_ident = variant.ident.to_string().to_kebab_case();
let message = group
.children
.iter()
.find(|child| child.id() == kebab_case_ident)
.unwrap();
let variant_ident = variant.ident;
idents.push(match variant.fields {
syn::Fields::Named(fields) => {
// Get the name of each field for pattern-matching
let field_idents = fields
.named
.iter()
.map(|field| field.ident.as_ref().unwrap())
.map(|ident| format_ident!("{}", ident.to_string().to_snake_case()));
quote!(#variant_ident { #(#field_idents),* })
}
syn::Fields::Unnamed(_) => todo!(),
syn::Fields::Unit => quote!(#variant_ident),
});
messages.push(message.to_syn());
}
quote! {
impl #ident {
fn localize(&self, plural_rules: &::icu_plurals::PluralRules) -> String {
match self {
#(Self::#idents => #messages),*
}
}
}
}
}
pub use parse_macro::derive_enum;
}
pub fn derive_enum(
&self,
ident: syn::Ident,
enum_data: syn::DataEnum,
) -> proc_macro2::TokenStream {
let mut idents = Vec::with_capacity(enum_data.variants.len());
let mut messages = Vec::with_capacity(enum_data.variants.len());
for variant in enum_data.variants {
let kebab_case_ident = variant.ident.to_string().to_kebab_case();
let message = self
.children
.iter()
.find(|child| child.id() == kebab_case_ident)
.unwrap();
let variant_ident = variant.ident;
idents.push(match variant.fields {
syn::Fields::Named(fields) => {
// Get the name of each field for pattern-matching
let field_idents = fields
.named
.iter()
.map(|field| field.ident.as_ref().unwrap())
.map(|ident| format_ident!("{}", ident.to_string().to_snake_case()));
quote!(#variant_ident { #(#field_idents),* })
}
syn::Fields::Unnamed(_) => todo!(),
syn::Fields::Unit => quote!(#variant_ident),
});
messages.push(message.to_syn());
}
quote! {
impl #ident {
fn localize(&self, plural_rules: &::icu_plurals::PluralRules) -> String {
match self {
#(Self::#idents => #messages),*
}
}
}
}