Add support for cardinal CLDR plural selectors

finchie
Feb 11, 2024, 1:52 PM
UOMQT7LTURIIWHZT2ZHLCJG6XESYTN26EJC7IHRFR4PYJ355PNYAC

Dependencies

  • [2] MIHGKLME Fix generated `format!` macro call
  • [3] BMUMO42I Add support for inline string and number literals
  • [4] 3C3CHSY5 Implement `to_syn` for groups containing simple text messages
  • [5] O77KA6C4 Create `fluent_embed` crate

Change contents

  • replacement in fluent_embed/src/lib.rs at line 2
    [3.26][3.26:111]()
    Entry, Expression, InlineExpression, Message, Pattern, PatternElement, Resource,
    [3.26]
    [3.111]
    Entry, Expression, InlineExpression, Message, Pattern, PatternElement, Resource, Variant,
    VariantKey,
  • replacement in fluent_embed/src/lib.rs at line 5
    [3.114][3.114:132]()
    use quote::quote;
    [3.114]
    [3.68]
    use heck::ToUpperCamelCase;
    use quote::{format_ident, quote};
  • replacement in fluent_embed/src/lib.rs at line 25
    [3.228][3.228:294]()
    .map_or_else(|| parse_quote!(()), match_pattern),
    [3.228]
    [3.554]
    .map_or_else(|| parse_quote!(()), match_fluent_pattern),
  • replacement in fluent_embed/src/lib.rs at line 61
    [3.296][3.296:384]()
    fn match_pattern<'resource>(pattern: &'resource Pattern<&'resource str>) -> syn::Expr {
    [3.296]
    [2.62]
    fn match_fluent_pattern<'resource>(pattern: &'resource Pattern<&'resource str>) -> syn::Expr {
  • replacement in fluent_embed/src/lib.rs at line 85
    [3.1235][3.1235:1323]()
    Expression::Select { selector, variants } => match_inline_expression(selector),
    [3.1235]
    [3.1323]
    Expression::Select { selector, variants } => {
    let match_target = match_inline_expression(selector);
    let match_arms: Vec<syn::Arm> = variants.iter().map(match_variant).collect();
    parse_quote! {
    {
    // FIXME: this is a hack and should be cleaned up later
    use icu_locid::locale;
    use icu_plurals::{PluralCategory, PluralRuleType, PluralRules};
    let plural_rules = PluralRules::try_new(&locale!("en").into(), PluralRuleType::Cardinal)
    .expect("locale should be present");
    match plural_rules.category_for(#match_target) {
    #(#match_arms),*
    }
    }
    }
    }
  • replacement in fluent_embed/src/lib.rs at line 122
    [3.2106][3.1018:1040](),[3.1018][3.1018:1040]()
    _ => todo!(),
    [3.2106]
    [3.1040]
    InlineExpression::VariableReference { id } => {
    let ident = format_ident!("{}", id.name);
    parse_quote!(#ident)
    }
    _ => {
    dbg!(expression);
    todo!()
    }
    }
    }
    fn match_variant<'resource>(variant: &Variant<&'resource str>) -> syn::Arm {
    let base_pattern = match_pattern(&variant.key);
    let body = match_fluent_pattern(&variant.value);
    // Default patterns match anything else
    // TODO: this can potentially generate unreachable patterns,
    // should be replaced with a more sophisticated implementation
    let pattern = if variant.default {
    parse_quote!(#base_pattern | _)
    } else {
    base_pattern
    };
    parse_quote!(#pattern => #body)
    }
    fn match_pattern<'resource>(pattern: &VariantKey<&'resource str>) -> syn::Pat {
    match pattern {
    VariantKey::Identifier { name } => {
    let ident = format_ident!("{}", name.to_upper_camel_case());
    parse_quote!(PluralCategory::#ident)
    }
    VariantKey::NumberLiteral { value } => todo!(),
  • replacement in fluent_embed/examples/groups.rs at line 5
    [3.1095][3.2107:2191]()
    let ftl = r#"test-message = the number is { 2 }! what a { "cool" } number :)"#;
    [3.1095]
    [3.1131]
    // Example from https://projectfluent.org/fluent/guide/selectors.html
    let ftl = r#"emails =
    { $unreadEmails ->
    [one] You have one unread email.
    *[other] You have { $unreadEmails } unread emails.
    }"#;