From c1d012ca97f3091f868b1a357683e41b7f0b6be2 Mon Sep 17 00:00:00 2001 From: "Shane F. Carr" Date: Sat, 15 Apr 2023 11:48:04 -0700 Subject: [PATCH 1/4] Add LocaleFallbackProvider to tutorial examples --- docs/tutorials/data_management.md | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/docs/tutorials/data_management.md b/docs/tutorials/data_management.md index 7427b7e7204..8dac89915cf 100644 --- a/docs/tutorials/data_management.md +++ b/docs/tutorials/data_management.md @@ -65,6 +65,7 @@ We can then use the provider in our code: use icu::locid::{locale, Locale}; use icu::calendar::DateTime; use icu::datetime::{DateTimeFormatter, options::length}; +use icu_provider_adapters::fallback::LocaleFallbackProvider; use icu_provider_blob::BlobDataProvider; const LOCALE: Locale = locale!("ja"); @@ -75,6 +76,11 @@ fn main() { BlobDataProvider::try_new_from_blob(blob.into_boxed_slice()) .expect("Failed to initialize Data Provider."); + // Wrapping the raw BlobDataProvider in a LocaleFallbackProvider enables + // locales to fall back to other locales, like "en-US" to "en". + let buffer_provider = LocaleFallbackProvider::try_new_with_buffer_provider(buffer_provider) + .expect("Provider should contain fallback rules"); + let options = length::Bag::from_date_time_style(length::Date::Long, length::Time::Medium); let dtf = DateTimeFormatter::try_new_with_buffer_provider(&buffer_provider, &LOCALE.into(), options.into()) @@ -109,6 +115,7 @@ We can instead use `TypedDateTimeFormatter`, which only supports form use icu::locid::{locale, Locale}; use icu::calendar::{DateTime, Gregorian}; use icu::datetime::{TypedDateTimeFormatter, options::length}; +use icu_provider_adapters::fallback::LocaleFallbackProvider; use icu_provider_blob::BlobDataProvider; const LOCALE: Locale = locale!("ja"); @@ -119,6 +126,11 @@ fn main() { BlobDataProvider::try_new_from_blob(blob.into_boxed_slice()) .expect("Failed to initialize Data Provider."); + // Wrapping the raw BlobDataProvider in a LocaleFallbackProvider enables + // locales to fall back to other locales, like "en-US" to "en". + let buffer_provider = LocaleFallbackProvider::try_new_with_buffer_provider(buffer_provider) + .expect("Provider should contain fallback rules"); + let options = length::Bag::from_date_time_style(length::Date::Long, length::Time::Medium); let dtf = TypedDateTimeFormatter::::try_new_with_buffer_provider(&buffer_provider, &LOCALE.into(), options.into()) @@ -178,6 +190,11 @@ impl_data_provider!(UnstableProvider); fn main() { let unstable_provider = UnstableProvider; + // Wrapping the raw UnstableProvider in a LocaleFallbackProvider enables + // locales to fall back to other locales, like "en-US" to "en". + let unstable_provider = LocaleFallbackProvider::try_new_unstable(unstable_provider) + .expect("Provider should contain fallback rules"); + let options = length::Bag::from_date_time_style(length::Date::Long, length::Time::Medium); let dtf = TypedDateTimeFormatter::try_new_unstable(&unstable_provider, &LOCALE.into(), options.into()) @@ -225,6 +242,7 @@ use icu::locid::{locale, Locale}; use icu::calendar::DateTime; use icu::datetime::{TypedDateTimeFormatter, options::length}; use icu_provider_fs::FsDataProvider; +use icu_provider_adapters::fallback::LocaleFallbackProvider; const LOCALE: Locale = locale!("ja"); @@ -232,6 +250,11 @@ fn main() { let buffer_provider = FsDataProvider::try_new("my-data-dir") .expect("Failed to initialize Data Provider"); + // Wrapping the raw BlobDataProvider in a LocaleFallbackProvider enables + // locales to fall back to other locales, like "en-US" to "en". + let buffer_provider = LocaleFallbackProvider::try_new_with_buffer_provider(buffer_provider) + .expect("Provider should contain fallback rules"); + let options = length::Bag::from_date_time_style(length::Date::Long, length::Time::Medium); let dtf = TypedDateTimeFormatter::try_new_with_buffer_provider(&buffer_provider, &LOCALE.into(), options.into()) From 87058d87937ad7726322d183c9447ef2d15d0ccc Mon Sep 17 00:00:00 2001 From: "Shane F. Carr" Date: Sat, 15 Apr 2023 11:52:12 -0700 Subject: [PATCH 2/4] Imports --- docs/tutorials/data_management.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/tutorials/data_management.md b/docs/tutorials/data_management.md index 8dac89915cf..ba08a61d5dc 100644 --- a/docs/tutorials/data_management.md +++ b/docs/tutorials/data_management.md @@ -180,6 +180,7 @@ extern crate alloc; // required as my-data-mod is written for #[no_std] use icu::locid::{locale, Locale}; use icu::calendar::DateTime; use icu::datetime::{TypedDateTimeFormatter, options::length}; +use icu_provider_adapters::fallback::LocaleFallbackProvider; const LOCALE: Locale = locale!("ja"); @@ -241,8 +242,8 @@ $ cargo add icu_provider_fs use icu::locid::{locale, Locale}; use icu::calendar::DateTime; use icu::datetime::{TypedDateTimeFormatter, options::length}; -use icu_provider_fs::FsDataProvider; use icu_provider_adapters::fallback::LocaleFallbackProvider; +use icu_provider_fs::FsDataProvider; const LOCALE: Locale = locale!("ja"); From bc8002f5cfabf3a15e40b6a17f3ea8448936e693 Mon Sep 17 00:00:00 2001 From: "Shane F. Carr" Date: Fri, 25 Aug 2023 19:22:50 -0700 Subject: [PATCH 3/4] Introduce why we need LocaleFallbackProvider --- docs/tutorials/data_management.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/tutorials/data_management.md b/docs/tutorials/data_management.md index ba08a61d5dc..b464ceb250e 100644 --- a/docs/tutorials/data_management.md +++ b/docs/tutorials/data_management.md @@ -46,6 +46,10 @@ You should generate it automatically at build time if: If you check in the generated data, it is recommended that you configure a job in continuous integration that verifies that the data in your repository reflects the latest CLDR/Unicode releases; otherwise, your app may drift out of date. +## Locale Fallbacking + +Data generated with `--format blob` or `--format fs` supports only exact matches for locales, not locales requiring _fallback_. For example, if `en-US` is requested but only `en` data is available, then the data request will fail. Because of this, it is often desirable to configure a `LocaleFallbackProvider`, as illustrated in the remainder of the examples on this page. + # 3. Using the generated data Once we have generated some data, it needs to be loaded as a data provider. The blob format we chose can be loaded by `BlobDataProvider` from the `icu_provider_blob` crate. From 65902449a3c2ebbb795a820946dbc372431b91a1 Mon Sep 17 00:00:00 2001 From: "Shane F. Carr" Date: Fri, 25 Aug 2023 19:36:02 -0700 Subject: [PATCH 4/4] Fix tutorials test? --- docs/tutorials/testing/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/tutorials/testing/Cargo.toml b/docs/tutorials/testing/Cargo.toml index a3447d76421..c40eab25cd3 100644 --- a/docs/tutorials/testing/Cargo.toml +++ b/docs/tutorials/testing/Cargo.toml @@ -14,7 +14,7 @@ displaydoc = "0.2.3" icu = "1.2" icu_datagen = { version = "1.2", default-features = false} icu_provider = { version = "1.2", features = ["deserialize_json"] } -icu_provider_adapters = "1.2" +icu_provider_adapters = { version = "1.2", features = ["serde"] } icu_provider_blob = "1.2" icu_provider_fs = "1.2" icu_testdata = "1.2"