Most of the changes are "noise" - the refactor touched most parts of the codebase. The main change is that instead of returning the output of format!, the generated code now calls writer.write_all() and returns an empty Ok(()) on success. This should make things a bit cleaner and hopefully reduce the amount of unncecessary allocation at compile-time.
3NMKD6I57ONAGHEN4PZIAV2KPYESVR4JL3DTWSHXKCMVJBEQ4GIQC CESJ4CTO26X4GBZBPXRXLOJT3JQJOGFN5EJSNAAZELNQRZF7QSYAC IRW6JACS3KVVA6HW5SBNBOHOQ2WRBHYGDND3FUWJYKJC7ZMOAVOQC AAERM7PBDVDFDEEXZ7UJ5WWQF7SPEJQQYXRBZ63ETB5YAVIECHMAC XEEXWJLGVIPIGURSDU4ETZMGAIFTFDPECM4QWFOSRHU7GMGVOUVQC HHJDRLLNN36UNIA7STAXEEVBCEMPJNB7SJQOS3TJLLYN4AEZ4MHQC NO3PDO7PY7J3WPADNCS5VD6HKFY63E23I3SDR4DHXNVQJTG27RAAC XGNME3WRU3MJDTFHUFJYARLVXWBZIH5ODBOIIFTXHNCBTZQH2R7QC 4MRF5E76QSW3EPICI6TNEGJ2KSBWODWMIDQPLYALDWBYWKAV5LJAC F5LG7WENUUDRSCTDMA4M6BAC5RWTGQO45C4ZEBZDX6FHCTTHBVGQC 5TEX4MNUC4LDDRMNEOVCFNUUEZAGUXMKO3OIEQFXWRQKXSHY2NRQC QFPQZR4K4UZ7R2GQZJG4NYBGVQJVL2ANIKGGTOHAMIRIBQHPSQGAC D652S2N3MHR7NJWSJIT7DUH5TPEFF6YII7EGV4C7IYWARXLMGAWQC HJMYJDC77NLU44QZWIW7CELXJKD4EK4YZ6CCILYBG6FWGZ2KMBVAC KZLFC7OWYNK3G5YNHRANUK3VUVCM6W6J34N7UABYA24XMZWAVVHQC 2SITVDYW6KANM24QXRHVSBL6S77UHKJLOSOHSUZQBJFL5NAAGQYAC BFL2Y7GN6NBXXNAUSD4M6T6CIVQ2OLERPE2CAFSLRF377WFFTVCQC 7U2DXFMPZO4P53AMWYCVXG3EPB7UIAPEY4PDDINX4TTABHD5NGMQC UKFEFT6LSI4K7X6UHQFZYD52DILKXMZMYSO2UYS2FCHNPXIF4BEQC fn localize(&self) -> String {let available_locales = #locales;let selected_locale = ::fluent_embed::locale_select::match_locales(&available_locales, &Self::CANONICAL_LOCALE);self.message_for_locale(&selected_locale)
fn message_for_locale(&self,writer: &mut W,locale: &::fluent_embed::icu_locid::LanguageIdentifier,) -> Result<(), ::fluent_embed::LocalizationError> {#message_body
let mut format_body = String::new();let mut format_arguments = Vec::new();
let mut write_expressions: Vec<syn::Expr> =Vec::with_capacity(message_context.pattern.elements.len());
PatternElement::TextElement { value } => format_body.push_str(value),
PatternElement::TextElement { value } => {let byte_string_literal = proc_macro2::Literal::byte_string(value.as_bytes());write_expressions.push(parse_quote!(writer.write_all(#byte_string_literal)?));}
let target = inline_expression(selector, message_context)?;let mut arms: Vec<syn::Arm> = Vec::with_capacity(variants.len());
let match_target = inline_expression(selector, message_context)?;let default_arm = OnceCell::new();let mut additional_arms = Vec::with_capacity(variants.len());
let ident = format_ident!("{}", name.to_pascal_case());parse_quote!(::fluent_embed::icu_plurals::PluralCategory::#ident)
let ident_pascal_case =format_ident!("{}", name.to_pascal_case());parse_quote!(::fluent_embed::icu_plurals::PluralCategory::#ident_pascal_case)
// Default patterns match anything else// TODO: this can potentially generate unreachable patterns,// should be replaced with a more sophisticated implementationlet pattern = if variant.default {parse_quote!(#base_pattern | _)
if variant.default {default_arm.set(quote!(#variant_pattern | _ => #variant_body)).expect("Multiple default patterns for match statement.");
let format_body_literal = proc_macro2::Literal::string(format_body.to_string().as_str());Ok(parse_quote!(format!(#format_body_literal, #(#format_arguments),*)))
Ok(parse_quote! {{#(#write_expressions;)*}})
impl Localize for RelativeTime {const CANONICAL_LOCALE: LanguageIdentifier = DEFAULT_LOCALE;
impl<W: std::io::Write> Localize<W> for RelativeTime {const CANONICAL_LOCALE: LanguageIdentifier = langid!("en-US");fn available_locales(&self) -> Vec<LanguageIdentifier> {// TODO: keep track of all locales with Fluent data, and return only thosevec![<Self as Localize<W>>::CANONICAL_LOCALE]}
pub trait Localize {
#[derive(thiserror::Error, Debug)]pub enum LocalizationError {#[error("invalid locale selected")]InvalidLocale,#[error("unable to write localized output")]IO(#[from] std::io::Error),}pub trait Localize<W: std::io::Write> {// TODO: this should be project-wide and tracked at build time
fn message_for_locale(&self, locale: &LanguageIdentifier) -> String;fn localize(&self) -> String;
fn available_locales(&self) -> Vec<LanguageIdentifier>;fn message_for_locale(&self,writer: &mut W,locale: &LanguageIdentifier,) -> Result<(), LocalizationError>;fn localize(&self, writer: &mut W) -> Result<(), LocalizationError> {let available_locales = self.available_locales();let selected_locale = locale_select::match_locales(&available_locales,&<Self as Localize<W>>::CANONICAL_LOCALE,);self.message_for_locale(writer, &selected_locale)}