Refactor how `Group` stores messages

finchie
Feb 24, 2024, 12:50 PM
BQ6N55O7RPG47G35YI37Z37456VKWT5KLGQKDQVAN2WI4K34TRBQC

Dependencies

  • [2] 3WEPY3OX Add `locale` parameter to derived `localize()` function
  • [3] HJMYJDC7 Simplify `fluent_embed::group` module
  • [4] 2XQ6ZB4W Store multiple locales in a single `Group`
  • [5] 5TEX4MNU Split `fluent_embed` into `group` and `parse` modules
  • [6] ROSR4HD5 Parse captured glob as locale

Change contents

  • replacement in fluent_embed/src/group.rs at line 8
    [3.486][3.486:622]()
    struct LocalizationsForMessage {
    canonical_message: Message<String>,
    pub additional_messages: HashMap<Locale, Message<String>>,
    [3.486]
    [3.622]
    struct LocaleGroup {
    locale: Locale,
    messages: Box<[Option<Message<String>>]>,
  • replacement in fluent_embed/src/group.rs at line 13
    [3.625][3.625:824](),[3.824][2.198:199](),[2.199][2.199:503](),[2.503][2.503:504](),[2.504][2.504:834]()
    impl LocalizationsForMessage {
    fn new(canonical_message: Message<String>) -> Self {
    Self {
    canonical_message,
    additional_messages: HashMap::new(),
    }
    }
    fn to_syn(&self, canonical_locale: String) -> syn::ExprBlock {
    let additional_locales = self
    .additional_messages
    .keys()
    .map(|locale| locale.to_string())
    .map(|locale_string| syn::LitStr::new(&locale_string, proc_macro2::Span::call_site()));
    let additional_messages = self
    .additional_messages
    .values()
    .map(crate::parse_fluent::message);
    let canonical_locale = syn::LitStr::new(&canonical_locale, proc_macro2::Span::call_site());
    let canonical_message = crate::parse_fluent::message(&self.canonical_message);
    [3.625]
    [2.834]
    impl LocaleGroup {
    fn new(
    locale: Locale,
    resource: Resource<String>,
    canonical_messages: &[Message<String>],
    ) -> Self {
    let mut messages = vec![None; canonical_messages.len()].into_boxed_slice();
  • replacement in fluent_embed/src/group.rs at line 21
    [2.835][2.835:974]()
    parse_quote! {
    {
    #(if locale.normalizing_eq(#additional_locales) { return #additional_messages })else*
    [2.835]
    [2.974]
    for entry in resource.body {
    if let Entry::Message(message) = entry {
    let index = canonical_messages
    .iter()
    .position(|canonical_message| canonical_message.id.name == message.id.name)
    .expect("Message ID must be in canonical group");
  • replacement in fluent_embed/src/group.rs at line 28
    [2.975][2.975:1077]()
    assert!(locale.normalizing_eq(#canonical_locale));
    #canonical_message
    [2.975]
    [2.1077]
    assert!(messages[index].is_none());
    messages[index] = Some(message);
  • edit in fluent_embed/src/group.rs at line 32
    [2.1101]
    [2.1101]
    Self { locale, messages }
  • replacement in fluent_embed/src/group.rs at line 40
    [3.857][3.857:913]()
    messages: HashMap<String, LocalizationsForMessage>,
    [3.857]
    [3.4310]
    canonical_messages: Vec<Message<String>>,
    extra_locales: Vec<LocaleGroup>,
  • replacement in fluent_embed/src/group.rs at line 48
    [3.4642][3.1095:1138]()
    let mut messages = HashMap::new();
    [3.4642]
    [3.4798]
    let mut canonical_messages = Vec::new();
  • replacement in fluent_embed/src/group.rs at line 52
    [3.1239][3.1239:1395]()
    messages.insert(
    message.id.name.clone(),
    LocalizationsForMessage::new(message),
    );
    [3.1239]
    [3.1395]
    canonical_messages.push(message);
  • replacement in fluent_embed/src/group.rs at line 56
    [3.4960][3.1410:1818]()
    for (locale, resource) in resources {
    for entry in resource.body {
    if let Entry::Message(message) = entry {
    let localizations = messages.get_mut(&message.id.name).unwrap();
    localizations
    .additional_messages
    .insert(locale.clone(), message);
    }
    }
    }
    [3.4960]
    [3.1818]
    let extra_locales = resources
    .into_iter()
    .map(|(locale, resource)| LocaleGroup::new(locale, resource, &canonical_messages))
    .collect::<Vec<_>>();
  • replacement in fluent_embed/src/group.rs at line 63
    [3.1864][3.1864:1886]()
    messages,
    [3.1864]
    [3.1886]
    canonical_messages,
    extra_locales,
  • replacement in fluent_embed/src/group.rs at line 68
    [3.1898][3.1898:2028]()
    pub fn canonical_message_for(&self, id: &str) -> &Message<String> {
    &self.messages.get(id).unwrap().canonical_message
    [3.1898]
    [2.1108]
    /// Returns an iterator over the localized messages paired with the relevant locale
    fn messages_in_column(
    &self,
    message_column: usize,
    ) -> impl Iterator<Item = (&Locale, &Message<String>)> {
    self.extra_locales.iter().filter_map(move |locale_group| {
    locale_group
    .messages
    .get(message_column)
    .unwrap()
    .as_ref()
    .map(|message| (&locale_group.locale, message))
    })
  • replacement in fluent_embed/src/group.rs at line 84
    [2.1171][2.1171:1291]()
    self.messages
    .get(id)
    .unwrap()
    .to_syn(self.canonical_locale.to_string())
    [2.1171]
    [3.2028]
    let canonical_locale = syn::LitStr::new(
    &self.canonical_locale.to_string(),
    proc_macro2::Span::call_site(),
    );
    let message_column = self
    .canonical_messages
    .iter()
    .position(|message| message.id.name == id)
    .expect("Message id must be valid");
    let canonical_message =
    crate::parse_fluent::message(&self.canonical_messages[message_column]);
    let additional_locale_names = self
    .messages_in_column(message_column)
    .map(|(locale, _message)| locale.to_string())
    .map(|locale_string| syn::LitStr::new(&locale_string, proc_macro2::Span::call_site()));
    let additional_locale_messages = self
    .messages_in_column(message_column)
    .map(|(_locale, message)| crate::parse_fluent::message(message));
    parse_quote! {{
    #(if locale.normalizing_eq(#additional_locale_names) { return #additional_locale_messages })else*
    assert!(locale.normalizing_eq(#canonical_locale));
    #canonical_message
    }}