Skip to content

Comments

Add BoundLocaleDataProvider and some impls for it#7621

Open
sffc wants to merge 9 commits intounicode-org:mainfrom
sffc:boundlocale
Open

Add BoundLocaleDataProvider and some impls for it#7621
sffc wants to merge 9 commits intounicode-org:mainfrom
sffc:boundlocale

Conversation

@sffc
Copy link
Member

@sffc sffc commented Feb 10, 2026

#3260

Please take a look at this design for a formatter that retains a piece of the data provider for runtime lookup of data marker attributes, intended for use cases such as currencies, units, and display names.

Reviewable commit-by-commit.

No AI was used when writing this, but I might use one to fix up the clippy and feature warnings in CI.

The docs are somewhat limited. Please focus on the docs tests for the end-to-end usage examples. I will add more docs before merging.

@sffc sffc requested review from a team and Manishearth as code owners February 10, 2026 05:13
@sffc sffc requested a review from robertbastian February 10, 2026 05:13
@sffc
Copy link
Member Author

sffc commented Feb 10, 2026

In case it helps, here's a summary of what you can do after this PR:

You can write code like

let formatter = HelloWorldAttributeFormatter::try_new_with_buffer_provider(
    &provider,
    locale!("en").into()
).unwrap();

assert_writeable_eq!(formatter.format("reverse").unwrap(), "Olleh Dlrow");
assert_writeable_eq!(formatter.format_for_prefix("rev").unwrap(), "Olleh Dlrow");

Please observe that the data marker attribute is given in the format function, not in the constructor.

To make this work, we save a small slice of the data provider structure inside of the HelloWorldAttributeFormatter, which has a generic parameter that varies based on the provider type, powered by some new traits.

This PR adds impls of the new traits in the BlobDataProvider and HelloWorldProvider universes. We will need to add them to baked data, and probably FsDataProvider.

Copy link
Member

@robertbastian robertbastian left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As far as I remember the display names design, it doesn't involve the formatter holding on to the provider. I don't think this approach gives nice APIs, as the formatters will need to be generic in the providers. This also requires a lot of new traits and types. Overall I'm very negative on this.

/// - `deserialize_bincode_1`
///
/// ✨ *Enabled with the `serde` Cargo feature.*
pub fn new(inner: &'a P) -> Self {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the canonical way to wrap a provider in a DeserializingBufferProvider is to call .as_deserializing(). we use this in a lot of docs, and I don't think we should introduce an alternative API that does the same

use alloc::boxed::Box;
use icu_provider::buf::BufferFormat;
use icu_provider::prelude::*;
use icu_provider::unstable::BindLocale;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if you start depending on unstable APIs, do we need to use a ~ dep?

/// assert_writeable_eq!(fmt.format("reverse").unwrap(), "Olleh Dlrow");
/// ```
#[derive(Debug)]
pub struct HelloWorldAttributeFormatter<P: BoundLocaleDataProvider<HelloWorldV1>> {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is this a bad example, or does this mean every formatter using this pattern needs to be generic in a provider?

@sffc
Copy link
Member Author

sffc commented Feb 10, 2026

The use case is when you need to load a list of many different data marker attributes.

If you load each one in sequence from a provider, you need to re-read the locale (and marker in the case of blob provider) for every lookup.

What this design does is it creates an intermediate "bound locale provider" that is halfway through a data load operation. You can then more efficiently perform attribute lookups.

@sffc
Copy link
Member Author

sffc commented Feb 18, 2026

See #7663 for benchmark results. @robertbastian

@sffc sffc added the discuss-priority Discuss at the next ICU4X meeting label Feb 23, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

discuss-priority Discuss at the next ICU4X meeting

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants