Change lists to be based on type (and, or, unit) rather than length (wide, short, narrow)

finchie
Aug 29, 2025, 7:58 AM
DJH52CL34NRGNCOD27PO2ZZ7QC6TBL5GAZKY2A5FLX55VJJU3ELQC

Dependencies

  • [2] 2HHBS7VW Add rudimentary support for localizing lists
  • [3] Q7LUHXXB Replace localization of `Vec<Localize>` with `List` type
  • [4] RA3H7PWC Refactor `Localize` for performance
  • [5] GOMTCPOL Pass colors through a field in `Context` rather than on `Styled` directly
  • [6] PGBXJWIH Move `l10n_embed` re-exports into `macro_prelude` module
  • [*] HHJDRLLN Create `fluent_embed_runtime` crate

Change contents

  • edit in l10n_embed/src/list.rs at line 2
    [2.90][3.32:151]()
    /// Re-export from [`icu_locale`] for convenience when constructing a [`List`]
    pub use icu_list::options::ListLength;
  • replacement in l10n_embed/src/list.rs at line 11
    [3.277][3.277:354]()
    pub struct List<L: Localize> {
    messages: Vec<L>,
    length: ListLength,
    [3.277]
    [2.510]
    pub enum ListType {
    And,
    Or,
    Unit,
  • replacement in l10n_embed/src/list.rs at line 17
    [2.513][3.355:488]()
    impl<L: Localize> List<L> {
    pub fn new(messages: Vec<L>, length: ListLength) -> Self {
    Self { messages, length }
    }
    }
    [2.513]
    [3.488]
    macro_rules! list_impl {
    ($list_name:ident, $list_type:path) => {
    pub struct $list_name<L: Localize> {
    messages: Vec<L>,
    }
  • replacement in l10n_embed/src/list.rs at line 23
    [3.489][3.489:593]()
    impl<L: Localize> Length for List<L> {
    fn len(&self) -> usize {
    self.messages.len()
    }
    }
    [3.489]
    [3.593]
    impl<L: Localize> $list_name<L> {
    pub fn new(messages: Vec<L>) -> Self {
    Self { messages }
    }
    }
  • replacement in l10n_embed/src/list.rs at line 29
    [3.594][3.594:635](),[3.635][4.6458:6589]()
    impl<L: Localize> Localize for List<L> {
    fn localize(&self, context: &Context, buffer: &mut String) {
    let list_formatter = context.list_formatter(self.length);
    [3.594]
    [4.6589]
    impl<L: Localize> Length for $list_name<L> {
    fn len(&self) -> usize {
    self.messages.len()
    }
    }
  • replacement in l10n_embed/src/list.rs at line 35
    [4.6590][4.6590:6756]()
    let localized_messages = self.messages.iter().map(|message| {
    let mut buffer = String::new();
    message.localize(context, &mut buffer);
    [4.6590]
    [3.874]
    impl<L: Localize> Localize for $list_name<L> {
    fn localize(&self, context: &Context, buffer: &mut String) {
    let list_formatter = context.list_formatter($list_type);
  • replacement in l10n_embed/src/list.rs at line 39
    [3.875][4.6757:6788]()
    buffer
    });
    [3.875]
    [3.1013]
    let localized_messages = self.messages.iter().map(|message| {
    let mut buffer = String::new();
    message.localize(context, &mut buffer);
  • replacement in l10n_embed/src/list.rs at line 43
    [3.1014][4.6789:6911](),[4.6911][3.1076:1082](),[3.1076][3.1076:1082]()
    let formatted_list = list_formatter.format(localized_messages);
    formatted_list.write_to(buffer).unwrap();
    }
    [3.1014]
    [3.1082]
    buffer
    });
    let formatted_list = list_formatter.format(localized_messages);
    formatted_list.write_to(buffer).unwrap();
    }
    }
    };
  • edit in l10n_embed/src/list.rs at line 52
    [3.1084]
    list_impl!(AndList, ListType::And);
    list_impl!(OrList, ListType::Or);
    list_impl!(UnitList, ListType::Unit);
  • replacement in l10n_embed/src/lib.rs at line 16
    [4.7188][4.7188:7247]()
    use icu_list::options::{ListFormatterOptions, ListLength};
    [4.7188]
    [4.7247]
    use icu_list::options::ListFormatterOptions;
  • replacement in l10n_embed/src/lib.rs at line 72
    [4.8391][4.8391:8642]()
    pub fn list_formatter(&self, length: ListLength) -> &ListFormatter {
    let index = match length {
    ListLength::Wide => 0,
    ListLength::Short => 1,
    ListLength::Narrow => 2,
    _ => unimplemented!(),
    [4.8391]
    [4.8642]
    pub fn list_formatter(&self, list_type: list::ListType) -> &ListFormatter {
    let index = match list_type {
    list::ListType::And => 0,
    list::ListType::Or => 1,
    list::ListType::Unit => 2,
  • replacement in l10n_embed/src/lib.rs at line 80
    [4.8707][4.8707:8892]()
    ListFormatter::try_new_and(
    ListFormatterPreferences::from(&self.locale),
    ListFormatterOptions::default().with_length(length),
    )
    [4.8707]
    [4.8892]
    let preferences = ListFormatterPreferences::from(&self.locale);
    let options = ListFormatterOptions::default();
    match list_type {
    list::ListType::And => ListFormatter::try_new_and(preferences, options),
    list::ListType::Or => ListFormatter::try_new_or(preferences, options),
    list::ListType::Unit => ListFormatter::try_new_unit(preferences, options),
    }
  • replacement in l10n_embed/examples/list.rs at line 4
    [4.15112][3.1248:1290](),[3.1248][3.1248:1290]()
    use l10n_embed::list::{List, ListLength};
    [4.15112]
    [4.15113]
    use l10n_embed::list::{AndList, OrList, UnitList};
  • replacement in l10n_embed/examples/list.rs at line 11
    [3.1462][3.1462:1660]()
    let narrow_list = List::new(items.clone(), ListLength::Narrow);
    let short_list = List::new(items.clone(), ListLength::Short);
    let wide_list = List::new(items.clone(), ListLength::Wide);
    [3.1462]
    [3.1660]
    let and_list = AndList::new(items.clone());
    let or_list = OrList::new(items.clone());
    let unit_list = UnitList::new(items.clone());
  • replacement in l10n_embed/examples/list.rs at line 17
    [4.15201][4.15201:15339]()
    ("Narrow list", Box::new(narrow_list)),
    ("Short list", Box::new(short_list)),
    ("Wide list", Box::new(wide_list)),
    [4.15201]
    [4.15339]
    ("And list", Box::new(and_list)),
    ("Or list", Box::new(or_list)),
    ("Unit list", Box::new(unit_list)),