Migrate from a map between locales and their messages to a table where each row heading is the locale, each column heading is the canonical message and each cell is an Option<Message>. This reduces unnecessary work and makes it much cleaner to query all localizations of a message (.is_some() for each row in the column for that message id).
BQ6N55O7RPG47G35YI37Z37456VKWT5KLGQKDQVAN2WI4K34TRBQC 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);
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();
parse_quote! {{#(if locale.normalizing_eq(#additional_locales) { return #additional_messages })else*
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");
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);}}}
let extra_locales = resources.into_iter().map(|(locale, resource)| LocaleGroup::new(locale, resource, &canonical_messages)).collect::<Vec<_>>();
pub fn canonical_message_for(&self, id: &str) -> &Message<String> {&self.messages.get(id).unwrap().canonical_message
/// Returns an iterator over the localized messages paired with the relevant localefn 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))})
self.messages.get(id).unwrap().to_syn(self.canonical_locale.to_string())
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}}