diff --git a/Cargo.toml b/Cargo.toml index 89a3dbea..0e025bbd 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -42,6 +42,11 @@ serde_json = "1.0" thiserror = "1.0" tokio = "1.0" unic-langid = "0.9" +icu_locid = "1.4" +icu_provider = "1.4" +icu_decimal = "1.4" +icu = { version = "1.4", default-features = false } +fixed_decimal = "0.5" fluent-bundle = { version = "0.15.3", path = "fluent-bundle" } fluent-fallback = { version = "0.7.1", path = "fluent-fallback" } diff --git a/fluent-bundle/Cargo.toml b/fluent-bundle/Cargo.toml index 0374d2b4..70008dde 100644 --- a/fluent-bundle/Cargo.toml +++ b/fluent-bundle/Cargo.toml @@ -24,8 +24,13 @@ include = [ ] [dependencies] +fixed_decimal = { workspace = true, features = ["ryu"] } fluent-langneg.workspace = true fluent-syntax.workspace = true +icu_decimal.workspace = true +icu_locid.workspace = true +icu_provider = { workspace = true, features = ["sync"] } +icu.workspace = true intl_pluralrules.workspace = true rustc-hash.workspace = true unic-langid.workspace = true diff --git a/fluent-bundle/examples/custom_type.rs b/fluent-bundle/examples/custom_type.rs index a6093732..ac0564db 100644 --- a/fluent-bundle/examples/custom_type.rs +++ b/fluent-bundle/examples/custom_type.rs @@ -102,7 +102,7 @@ impl FluentType for DateTime { } fn as_string(&self, intls: &intl_memoizer::IntlLangMemoizer) -> std::borrow::Cow<'static, str> { intls - .with_try_get::((self.options.clone(),), |dtf| { + .with_try_get::((self.options.clone(),), &(), |dtf| { dtf.format(self.epoch).into() }) .expect("Failed to format a date.") @@ -138,7 +138,13 @@ impl DateTimeFormatter { impl Memoizable for DateTimeFormatter { type Args = (DateTimeOptions,); type Error = (); - fn construct(lang: LanguageIdentifier, args: Self::Args) -> Result { + type DataProvider = (); + + fn construct( + lang: LanguageIdentifier, + args: Self::Args, + _: &Self::DataProvider, + ) -> Result { Self::new(lang, args.0) } } diff --git a/fluent-bundle/src/bundle.rs b/fluent-bundle/src/bundle.rs index 41a00e24..4a1cd1f4 100644 --- a/fluent-bundle/src/bundle.rs +++ b/fluent-bundle/src/bundle.rs @@ -4,6 +4,7 @@ //! internationalization formatters, functions, scopeironmental variables and are expected to be used //! together. +use icu_provider::AnyProvider; use rustc_hash::FxHashMap; use std::borrow::Borrow; use std::borrow::Cow; @@ -25,6 +26,8 @@ use crate::resolver::{ResolveValue, Scope, WriteValue}; use crate::resource::FluentResource; use crate::types::FluentValue; +pub type IcuDataProvider = Box; + /// A collection of localization messages for a single locale, which are meant /// to be used together in a single view, widget or any other UI abstraction. /// @@ -141,6 +144,7 @@ pub struct FluentBundle { pub(crate) use_isolating: bool, pub(crate) transform: Option Cow>, pub(crate) formatter: Option Option>, + pub(crate) icu_data_provider: Option, } impl FluentBundle { @@ -548,6 +552,10 @@ impl FluentBundle { } } + pub fn set_icu_data_provider(&mut self, provider: IcuDataProvider) { + self.icu_data_provider = Some(provider); + } + /// Adds the builtin functions described in the [FTL syntax guide] to the bundle, making them /// available in messages. /// @@ -641,6 +649,7 @@ impl FluentBundle { use_isolating: true, transform: None, formatter: None, + icu_data_provider: None, } } } @@ -653,14 +662,19 @@ impl crate::memoizer::MemoizerKind for IntlLangMemoizer { Self::new(lang) } - fn with_try_get_threadsafe(&self, args: I::Args, cb: U) -> Result + fn with_try_get_threadsafe( + &self, + args: I::Args, + data_provider: &I::DataProvider, + cb: U, + ) -> Result where Self: Sized, I: intl_memoizer::Memoizable + Send + Sync + 'static, I::Args: Send + Sync + 'static, U: FnOnce(&I) -> R, { - self.with_try_get(args, cb) + self.with_try_get(args, data_provider, cb) } fn stringify_value( diff --git a/fluent-bundle/src/concurrent.rs b/fluent-bundle/src/concurrent.rs index de55f0a3..c2afc320 100644 --- a/fluent-bundle/src/concurrent.rs +++ b/fluent-bundle/src/concurrent.rs @@ -39,6 +39,7 @@ impl FluentBundle { use_isolating: true, transform: None, formatter: None, + icu_data_provider: None, } } } @@ -51,14 +52,19 @@ impl MemoizerKind for IntlLangMemoizer { Self::new(lang) } - fn with_try_get_threadsafe(&self, args: I::Args, cb: U) -> Result + fn with_try_get_threadsafe( + &self, + args: I::Args, + data_provider: &I::DataProvider, + cb: U, + ) -> Result where Self: Sized, I: Memoizable + Send + Sync + 'static, I::Args: Send + Sync + 'static, U: FnOnce(&I) -> R, { - self.with_try_get(args, cb) + self.with_try_get(args, data_provider, cb) } fn stringify_value(&self, value: &dyn FluentType) -> std::borrow::Cow<'static, str> { diff --git a/fluent-bundle/src/icu4x_data/any.rs b/fluent-bundle/src/icu4x_data/any.rs new file mode 100644 index 00000000..6fedf866 --- /dev/null +++ b/fluent-bundle/src/icu4x_data/any.rs @@ -0,0 +1,2 @@ +// @generated +impl_any_provider ! (BakedDataProvider) ; \ No newline at end of file diff --git a/fluent-bundle/src/icu4x_data/macros.rs b/fluent-bundle/src/icu4x_data/macros.rs new file mode 100644 index 00000000..92488c17 --- /dev/null +++ b/fluent-bundle/src/icu4x_data/macros.rs @@ -0,0 +1,2 @@ +// @generated +# [doc = r" Marks a type as a data provider. You can then use macros like"] # [doc = r" `impl_core_helloworld_v1` to add implementations."] # [doc = r""] # [doc = r" ```ignore"] # [doc = r" struct MyProvider;"] # [doc = r" const _: () = {"] # [doc = r#" include!("path/to/generated/macros.rs");"#] # [doc = r" make_provider!(MyProvider);"] # [doc = r" impl_core_helloworld_v1!(MyProvider);"] # [doc = r" }"] # [doc = r" ```"] # [doc (hidden)] # [macro_export] macro_rules ! __make_provider { ($ name : ty) => { # [clippy :: msrv = "1.67"] impl $ name { # [doc (hidden)] # [allow (dead_code)] pub const MUST_USE_MAKE_PROVIDER_MACRO : () = () ; } } ; } # [doc (inline)] pub use __make_provider as make_provider ; # [macro_use] # [path = "macros/decimal_symbols_v1.rs.data"] mod decimal_symbols_v1 ; # [doc (inline)] pub use __impl_decimal_symbols_v1 as impl_decimal_symbols_v1 ; \ No newline at end of file diff --git a/fluent-bundle/src/icu4x_data/macros/decimal_symbols_v1.rs.data b/fluent-bundle/src/icu4x_data/macros/decimal_symbols_v1.rs.data new file mode 100644 index 00000000..0e03de9c --- /dev/null +++ b/fluent-bundle/src/icu4x_data/macros/decimal_symbols_v1.rs.data @@ -0,0 +1,2 @@ +// @generated +# [doc = " Implement `DataProvider` on the given struct using the data"] # [doc = r" hardcoded in this file. This allows the struct to be used with"] # [doc = r" `icu`'s `_unstable` constructors."] # [doc (hidden)] # [macro_export] macro_rules ! __impl_decimal_symbols_v1 { ($ provider : ty) => { # [clippy :: msrv = "1.67"] const _ : () = < $ provider > :: MUST_USE_MAKE_PROVIDER_MACRO ; # [clippy :: msrv = "1.67"] impl icu_provider :: DataProvider < icu::decimal :: provider :: DecimalSymbolsV1Marker > for $ provider { fn load (& self , req : icu_provider :: DataRequest ,) -> Result < icu_provider :: DataResponse < icu::decimal :: provider :: DecimalSymbolsV1Marker > , icu_provider :: DataError > { static MN_MONG_MN : < icu::decimal :: provider :: DecimalSymbolsV1Marker as icu_provider :: DataMarker > :: Yokeable = icu::decimal :: provider :: DecimalSymbolsV1 { minus_sign_affixes : icu::decimal :: provider :: AffixesV1 { prefix : alloc :: borrow :: Cow :: Borrowed ("-") , suffix : alloc :: borrow :: Cow :: Borrowed ("") , } , plus_sign_affixes : icu::decimal :: provider :: AffixesV1 { prefix : alloc :: borrow :: Cow :: Borrowed ("+") , suffix : alloc :: borrow :: Cow :: Borrowed ("") , } , decimal_separator : alloc :: borrow :: Cow :: Borrowed (",") , grouping_separator : alloc :: borrow :: Cow :: Borrowed (",") , grouping_sizes : icu::decimal :: provider :: GroupingSizesV1 { primary : 3u8 , secondary : 3u8 , min_grouping : 1u8 , } , digits : ['0' , '1' , '2' , '3' , '4' , '5' , '6' , '7' , '8' , '9'] , } ; static MN_MONG_MN_U_NU_MONG : < icu::decimal :: provider :: DecimalSymbolsV1Marker as icu_provider :: DataMarker > :: Yokeable = icu::decimal :: provider :: DecimalSymbolsV1 { minus_sign_affixes : icu::decimal :: provider :: AffixesV1 { prefix : alloc :: borrow :: Cow :: Borrowed ("-") , suffix : alloc :: borrow :: Cow :: Borrowed ("") , } , plus_sign_affixes : icu::decimal :: provider :: AffixesV1 { prefix : alloc :: borrow :: Cow :: Borrowed ("+") , suffix : alloc :: borrow :: Cow :: Borrowed ("") , } , decimal_separator : alloc :: borrow :: Cow :: Borrowed (",") , grouping_separator : alloc :: borrow :: Cow :: Borrowed (",") , grouping_sizes : icu::decimal :: provider :: GroupingSizesV1 { primary : 3u8 , secondary : 3u8 , min_grouping : 1u8 , } , digits : ['᠐' , '᠑' , '᠒' , '᠓' , '᠔' , '᠕' , '᠖' , '᠗' , '᠘' , '᠙'] , } ; static AST : < icu::decimal :: provider :: DecimalSymbolsV1Marker as icu_provider :: DataMarker > :: Yokeable = icu::decimal :: provider :: DecimalSymbolsV1 { minus_sign_affixes : icu::decimal :: provider :: AffixesV1 { prefix : alloc :: borrow :: Cow :: Borrowed ("-") , suffix : alloc :: borrow :: Cow :: Borrowed ("") , } , plus_sign_affixes : icu::decimal :: provider :: AffixesV1 { prefix : alloc :: borrow :: Cow :: Borrowed ("+") , suffix : alloc :: borrow :: Cow :: Borrowed ("") , } , decimal_separator : alloc :: borrow :: Cow :: Borrowed (",") , grouping_separator : alloc :: borrow :: Cow :: Borrowed (".") , grouping_sizes : icu::decimal :: provider :: GroupingSizesV1 { primary : 3u8 , secondary : 3u8 , min_grouping : 1u8 , } , digits : ['0' , '1' , '2' , '3' , '4' , '5' , '6' , '7' , '8' , '9'] , } ; static LO_U_NU_LAOO : < icu::decimal :: provider :: DecimalSymbolsV1Marker as icu_provider :: DataMarker > :: Yokeable = icu::decimal :: provider :: DecimalSymbolsV1 { minus_sign_affixes : icu::decimal :: provider :: AffixesV1 { prefix : alloc :: borrow :: Cow :: Borrowed ("-") , suffix : alloc :: borrow :: Cow :: Borrowed ("") , } , plus_sign_affixes : icu::decimal :: provider :: AffixesV1 { prefix : alloc :: borrow :: Cow :: Borrowed ("+") , suffix : alloc :: borrow :: Cow :: Borrowed ("") , } , decimal_separator : alloc :: borrow :: Cow :: Borrowed (",") , grouping_separator : alloc :: borrow :: Cow :: Borrowed (".") , grouping_sizes : icu::decimal :: provider :: GroupingSizesV1 { primary : 3u8 , secondary : 3u8 , min_grouping : 1u8 , } , digits : ['໐' , '໑' , '໒' , '໓' , '໔' , '໕' , '໖' , '໗' , '໘' , '໙'] , } ; static KM_U_NU_KHMR : < icu::decimal :: provider :: DecimalSymbolsV1Marker as icu_provider :: DataMarker > :: Yokeable = icu::decimal :: provider :: DecimalSymbolsV1 { minus_sign_affixes : icu::decimal :: provider :: AffixesV1 { prefix : alloc :: borrow :: Cow :: Borrowed ("-") , suffix : alloc :: borrow :: Cow :: Borrowed ("") , } , plus_sign_affixes : icu::decimal :: provider :: AffixesV1 { prefix : alloc :: borrow :: Cow :: Borrowed ("+") , suffix : alloc :: borrow :: Cow :: Borrowed ("") , } , decimal_separator : alloc :: borrow :: Cow :: Borrowed (",") , grouping_separator : alloc :: borrow :: Cow :: Borrowed (".") , grouping_sizes : icu::decimal :: provider :: GroupingSizesV1 { primary : 3u8 , secondary : 3u8 , min_grouping : 1u8 , } , digits : ['០' , '១' , '២' , '៣' , '៤' , '៥' , '៦' , '៧' , '៨' , '៩'] , } ; static JV_U_NU_JAVA : < icu::decimal :: provider :: DecimalSymbolsV1Marker as icu_provider :: DataMarker > :: Yokeable = icu::decimal :: provider :: DecimalSymbolsV1 { minus_sign_affixes : icu::decimal :: provider :: AffixesV1 { prefix : alloc :: borrow :: Cow :: Borrowed ("-") , suffix : alloc :: borrow :: Cow :: Borrowed ("") , } , plus_sign_affixes : icu::decimal :: provider :: AffixesV1 { prefix : alloc :: borrow :: Cow :: Borrowed ("+") , suffix : alloc :: borrow :: Cow :: Borrowed ("") , } , decimal_separator : alloc :: borrow :: Cow :: Borrowed (",") , grouping_separator : alloc :: borrow :: Cow :: Borrowed (".") , grouping_sizes : icu::decimal :: provider :: GroupingSizesV1 { primary : 3u8 , secondary : 3u8 , min_grouping : 1u8 , } , digits : ['꧐' , '꧑' , '꧒' , '꧓' , '꧔' , '꧕' , '꧖' , '꧗' , '꧘' , '꧙'] , } ; static ES : < icu::decimal :: provider :: DecimalSymbolsV1Marker as icu_provider :: DataMarker > :: Yokeable = icu::decimal :: provider :: DecimalSymbolsV1 { minus_sign_affixes : icu::decimal :: provider :: AffixesV1 { prefix : alloc :: borrow :: Cow :: Borrowed ("-") , suffix : alloc :: borrow :: Cow :: Borrowed ("") , } , plus_sign_affixes : icu::decimal :: provider :: AffixesV1 { prefix : alloc :: borrow :: Cow :: Borrowed ("+") , suffix : alloc :: borrow :: Cow :: Borrowed ("") , } , decimal_separator : alloc :: borrow :: Cow :: Borrowed (",") , grouping_separator : alloc :: borrow :: Cow :: Borrowed (".") , grouping_sizes : icu::decimal :: provider :: GroupingSizesV1 { primary : 3u8 , secondary : 3u8 , min_grouping : 2u8 , } , digits : ['0' , '1' , '2' , '3' , '4' , '5' , '6' , '7' , '8' , '9'] , } ; static FR : < icu::decimal :: provider :: DecimalSymbolsV1Marker as icu_provider :: DataMarker > :: Yokeable = icu::decimal :: provider :: DecimalSymbolsV1 { minus_sign_affixes : icu::decimal :: provider :: AffixesV1 { prefix : alloc :: borrow :: Cow :: Borrowed ("-") , suffix : alloc :: borrow :: Cow :: Borrowed ("") , } , plus_sign_affixes : icu::decimal :: provider :: AffixesV1 { prefix : alloc :: borrow :: Cow :: Borrowed ("+") , suffix : alloc :: borrow :: Cow :: Borrowed ("") , } , decimal_separator : alloc :: borrow :: Cow :: Borrowed (",") , grouping_separator : alloc :: borrow :: Cow :: Borrowed ("\u{202f}") , grouping_sizes : icu::decimal :: provider :: GroupingSizesV1 { primary : 3u8 , secondary : 3u8 , min_grouping : 1u8 , } , digits : ['0' , '1' , '2' , '3' , '4' , '5' , '6' , '7' , '8' , '9'] , } ; static TOK : < icu::decimal :: provider :: DecimalSymbolsV1Marker as icu_provider :: DataMarker > :: Yokeable = icu::decimal :: provider :: DecimalSymbolsV1 { minus_sign_affixes : icu::decimal :: provider :: AffixesV1 { prefix : alloc :: borrow :: Cow :: Borrowed ("-") , suffix : alloc :: borrow :: Cow :: Borrowed ("") , } , plus_sign_affixes : icu::decimal :: provider :: AffixesV1 { prefix : alloc :: borrow :: Cow :: Borrowed ("+") , suffix : alloc :: borrow :: Cow :: Borrowed ("") , } , decimal_separator : alloc :: borrow :: Cow :: Borrowed (",") , grouping_separator : alloc :: borrow :: Cow :: Borrowed ("\u{a0}") , grouping_sizes : icu::decimal :: provider :: GroupingSizesV1 { primary : 2u8 , secondary : 2u8 , min_grouping : 1u8 , } , digits : ['0' , '1' , '2' , '3' , '4' , '5' , '6' , '7' , '8' , '9'] , } ; static AF : < icu::decimal :: provider :: DecimalSymbolsV1Marker as icu_provider :: DataMarker > :: Yokeable = icu::decimal :: provider :: DecimalSymbolsV1 { minus_sign_affixes : icu::decimal :: provider :: AffixesV1 { prefix : alloc :: borrow :: Cow :: Borrowed ("-") , suffix : alloc :: borrow :: Cow :: Borrowed ("") , } , plus_sign_affixes : icu::decimal :: provider :: AffixesV1 { prefix : alloc :: borrow :: Cow :: Borrowed ("+") , suffix : alloc :: borrow :: Cow :: Borrowed ("") , } , decimal_separator : alloc :: borrow :: Cow :: Borrowed (",") , grouping_separator : alloc :: borrow :: Cow :: Borrowed ("\u{a0}") , grouping_sizes : icu::decimal :: provider :: GroupingSizesV1 { primary : 3u8 , secondary : 3u8 , min_grouping : 1u8 , } , digits : ['0' , '1' , '2' , '3' , '4' , '5' , '6' , '7' , '8' , '9'] , } ; static BE : < icu::decimal :: provider :: DecimalSymbolsV1Marker as icu_provider :: DataMarker > :: Yokeable = icu::decimal :: provider :: DecimalSymbolsV1 { minus_sign_affixes : icu::decimal :: provider :: AffixesV1 { prefix : alloc :: borrow :: Cow :: Borrowed ("-") , suffix : alloc :: borrow :: Cow :: Borrowed ("") , } , plus_sign_affixes : icu::decimal :: provider :: AffixesV1 { prefix : alloc :: borrow :: Cow :: Borrowed ("+") , suffix : alloc :: borrow :: Cow :: Borrowed ("") , } , decimal_separator : alloc :: borrow :: Cow :: Borrowed (",") , grouping_separator : alloc :: borrow :: Cow :: Borrowed ("\u{a0}") , grouping_sizes : icu::decimal :: provider :: GroupingSizesV1 { primary : 3u8 , secondary : 3u8 , min_grouping : 2u8 , } , digits : ['0' , '1' , '2' , '3' , '4' , '5' , '6' , '7' , '8' , '9'] , } ; static LMO : < icu::decimal :: provider :: DecimalSymbolsV1Marker as icu_provider :: DataMarker > :: Yokeable = icu::decimal :: provider :: DecimalSymbolsV1 { minus_sign_affixes : icu::decimal :: provider :: AffixesV1 { prefix : alloc :: borrow :: Cow :: Borrowed ("-") , suffix : alloc :: borrow :: Cow :: Borrowed ("") , } , plus_sign_affixes : icu::decimal :: provider :: AffixesV1 { prefix : alloc :: borrow :: Cow :: Borrowed ("+") , suffix : alloc :: borrow :: Cow :: Borrowed ("") , } , decimal_separator : alloc :: borrow :: Cow :: Borrowed (",") , grouping_separator : alloc :: borrow :: Cow :: Borrowed ("’") , grouping_sizes : icu::decimal :: provider :: GroupingSizesV1 { primary : 3u8 , secondary : 3u8 , min_grouping : 1u8 , } , digits : ['0' , '1' , '2' , '3' , '4' , '5' , '6' , '7' , '8' , '9'] , } ; static AS_U_NU_LATN : < icu::decimal :: provider :: DecimalSymbolsV1Marker as icu_provider :: DataMarker > :: Yokeable = icu::decimal :: provider :: DecimalSymbolsV1 { minus_sign_affixes : icu::decimal :: provider :: AffixesV1 { prefix : alloc :: borrow :: Cow :: Borrowed ("-") , suffix : alloc :: borrow :: Cow :: Borrowed ("") , } , plus_sign_affixes : icu::decimal :: provider :: AffixesV1 { prefix : alloc :: borrow :: Cow :: Borrowed ("+") , suffix : alloc :: borrow :: Cow :: Borrowed ("") , } , decimal_separator : alloc :: borrow :: Cow :: Borrowed (".") , grouping_separator : alloc :: borrow :: Cow :: Borrowed (",") , grouping_sizes : icu::decimal :: provider :: GroupingSizesV1 { primary : 3u8 , secondary : 2u8 , min_grouping : 1u8 , } , digits : ['0' , '1' , '2' , '3' , '4' , '5' , '6' , '7' , '8' , '9'] , } ; static BRX_U_NU_DEVA : < icu::decimal :: provider :: DecimalSymbolsV1Marker as icu_provider :: DataMarker > :: Yokeable = icu::decimal :: provider :: DecimalSymbolsV1 { minus_sign_affixes : icu::decimal :: provider :: AffixesV1 { prefix : alloc :: borrow :: Cow :: Borrowed ("-") , suffix : alloc :: borrow :: Cow :: Borrowed ("") , } , plus_sign_affixes : icu::decimal :: provider :: AffixesV1 { prefix : alloc :: borrow :: Cow :: Borrowed ("+") , suffix : alloc :: borrow :: Cow :: Borrowed ("") , } , decimal_separator : alloc :: borrow :: Cow :: Borrowed (".") , grouping_separator : alloc :: borrow :: Cow :: Borrowed (",") , grouping_sizes : icu::decimal :: provider :: GroupingSizesV1 { primary : 3u8 , secondary : 2u8 , min_grouping : 1u8 , } , digits : ['०' , '१' , '२' , '३' , '४' , '५' , '६' , '७' , '८' , '९'] , } ; static AS : < icu::decimal :: provider :: DecimalSymbolsV1Marker as icu_provider :: DataMarker > :: Yokeable = icu::decimal :: provider :: DecimalSymbolsV1 { minus_sign_affixes : icu::decimal :: provider :: AffixesV1 { prefix : alloc :: borrow :: Cow :: Borrowed ("-") , suffix : alloc :: borrow :: Cow :: Borrowed ("") , } , plus_sign_affixes : icu::decimal :: provider :: AffixesV1 { prefix : alloc :: borrow :: Cow :: Borrowed ("+") , suffix : alloc :: borrow :: Cow :: Borrowed ("") , } , decimal_separator : alloc :: borrow :: Cow :: Borrowed (".") , grouping_separator : alloc :: borrow :: Cow :: Borrowed (",") , grouping_sizes : icu::decimal :: provider :: GroupingSizesV1 { primary : 3u8 , secondary : 2u8 , min_grouping : 1u8 , } , digits : ['০' , '১' , '২' , '৩' , '৪' , '৫' , '৬' , '৭' , '৮' , '৯'] , } ; static PA_U_NU_GURU : < icu::decimal :: provider :: DecimalSymbolsV1Marker as icu_provider :: DataMarker > :: Yokeable = icu::decimal :: provider :: DecimalSymbolsV1 { minus_sign_affixes : icu::decimal :: provider :: AffixesV1 { prefix : alloc :: borrow :: Cow :: Borrowed ("-") , suffix : alloc :: borrow :: Cow :: Borrowed ("") , } , plus_sign_affixes : icu::decimal :: provider :: AffixesV1 { prefix : alloc :: borrow :: Cow :: Borrowed ("+") , suffix : alloc :: borrow :: Cow :: Borrowed ("") , } , decimal_separator : alloc :: borrow :: Cow :: Borrowed (".") , grouping_separator : alloc :: borrow :: Cow :: Borrowed (",") , grouping_sizes : icu::decimal :: provider :: GroupingSizesV1 { primary : 3u8 , secondary : 2u8 , min_grouping : 1u8 , } , digits : ['੦' , '੧' , '੨' , '੩' , '੪' , '੫' , '੬' , '੭' , '੮' , '੯'] , } ; static GU_U_NU_GUJR : < icu::decimal :: provider :: DecimalSymbolsV1Marker as icu_provider :: DataMarker > :: Yokeable = icu::decimal :: provider :: DecimalSymbolsV1 { minus_sign_affixes : icu::decimal :: provider :: AffixesV1 { prefix : alloc :: borrow :: Cow :: Borrowed ("-") , suffix : alloc :: borrow :: Cow :: Borrowed ("") , } , plus_sign_affixes : icu::decimal :: provider :: AffixesV1 { prefix : alloc :: borrow :: Cow :: Borrowed ("+") , suffix : alloc :: borrow :: Cow :: Borrowed ("") , } , decimal_separator : alloc :: borrow :: Cow :: Borrowed (".") , grouping_separator : alloc :: borrow :: Cow :: Borrowed (",") , grouping_sizes : icu::decimal :: provider :: GroupingSizesV1 { primary : 3u8 , secondary : 2u8 , min_grouping : 1u8 , } , digits : ['૦' , '૧' , '૨' , '૩' , '૪' , '૫' , '૬' , '૭' , '૮' , '૯'] , } ; static KXV_ORYA_U_NU_ORYA : < icu::decimal :: provider :: DecimalSymbolsV1Marker as icu_provider :: DataMarker > :: Yokeable = icu::decimal :: provider :: DecimalSymbolsV1 { minus_sign_affixes : icu::decimal :: provider :: AffixesV1 { prefix : alloc :: borrow :: Cow :: Borrowed ("-") , suffix : alloc :: borrow :: Cow :: Borrowed ("") , } , plus_sign_affixes : icu::decimal :: provider :: AffixesV1 { prefix : alloc :: borrow :: Cow :: Borrowed ("+") , suffix : alloc :: borrow :: Cow :: Borrowed ("") , } , decimal_separator : alloc :: borrow :: Cow :: Borrowed (".") , grouping_separator : alloc :: borrow :: Cow :: Borrowed (",") , grouping_sizes : icu::decimal :: provider :: GroupingSizesV1 { primary : 3u8 , secondary : 2u8 , min_grouping : 1u8 , } , digits : ['୦' , '୧' , '୨' , '୩' , '୪' , '୫' , '୬' , '୭' , '୮' , '୯'] , } ; static TA_LK_U_NU_TAMLDEC : < icu::decimal :: provider :: DecimalSymbolsV1Marker as icu_provider :: DataMarker > :: Yokeable = icu::decimal :: provider :: DecimalSymbolsV1 { minus_sign_affixes : icu::decimal :: provider :: AffixesV1 { prefix : alloc :: borrow :: Cow :: Borrowed ("-") , suffix : alloc :: borrow :: Cow :: Borrowed ("") , } , plus_sign_affixes : icu::decimal :: provider :: AffixesV1 { prefix : alloc :: borrow :: Cow :: Borrowed ("+") , suffix : alloc :: borrow :: Cow :: Borrowed ("") , } , decimal_separator : alloc :: borrow :: Cow :: Borrowed (".") , grouping_separator : alloc :: borrow :: Cow :: Borrowed (",") , grouping_sizes : icu::decimal :: provider :: GroupingSizesV1 { primary : 3u8 , secondary : 2u8 , min_grouping : 1u8 , } , digits : ['௦' , '௧' , '௨' , '௩' , '௪' , '௫' , '௬' , '௭' , '௮' , '௯'] , } ; static KXV_TELU_U_NU_TELU : < icu::decimal :: provider :: DecimalSymbolsV1Marker as icu_provider :: DataMarker > :: Yokeable = icu::decimal :: provider :: DecimalSymbolsV1 { minus_sign_affixes : icu::decimal :: provider :: AffixesV1 { prefix : alloc :: borrow :: Cow :: Borrowed ("-") , suffix : alloc :: borrow :: Cow :: Borrowed ("") , } , plus_sign_affixes : icu::decimal :: provider :: AffixesV1 { prefix : alloc :: borrow :: Cow :: Borrowed ("+") , suffix : alloc :: borrow :: Cow :: Borrowed ("") , } , decimal_separator : alloc :: borrow :: Cow :: Borrowed (".") , grouping_separator : alloc :: borrow :: Cow :: Borrowed (",") , grouping_sizes : icu::decimal :: provider :: GroupingSizesV1 { primary : 3u8 , secondary : 2u8 , min_grouping : 1u8 , } , digits : ['౦' , '౧' , '౨' , '౩' , '౪' , '౫' , '౬' , '౭' , '౮' , '౯'] , } ; static ML_U_NU_MLYM : < icu::decimal :: provider :: DecimalSymbolsV1Marker as icu_provider :: DataMarker > :: Yokeable = icu::decimal :: provider :: DecimalSymbolsV1 { minus_sign_affixes : icu::decimal :: provider :: AffixesV1 { prefix : alloc :: borrow :: Cow :: Borrowed ("-") , suffix : alloc :: borrow :: Cow :: Borrowed ("") , } , plus_sign_affixes : icu::decimal :: provider :: AffixesV1 { prefix : alloc :: borrow :: Cow :: Borrowed ("+") , suffix : alloc :: borrow :: Cow :: Borrowed ("") , } , decimal_separator : alloc :: borrow :: Cow :: Borrowed (".") , grouping_separator : alloc :: borrow :: Cow :: Borrowed (",") , grouping_sizes : icu::decimal :: provider :: GroupingSizesV1 { primary : 3u8 , secondary : 2u8 , min_grouping : 1u8 , } , digits : ['൦' , '൧' , '൨' , '൩' , '൪' , '൫' , '൬' , '൭' , '൮' , '൯'] , } ; static DZ : < icu::decimal :: provider :: DecimalSymbolsV1Marker as icu_provider :: DataMarker > :: Yokeable = icu::decimal :: provider :: DecimalSymbolsV1 { minus_sign_affixes : icu::decimal :: provider :: AffixesV1 { prefix : alloc :: borrow :: Cow :: Borrowed ("-") , suffix : alloc :: borrow :: Cow :: Borrowed ("") , } , plus_sign_affixes : icu::decimal :: provider :: AffixesV1 { prefix : alloc :: borrow :: Cow :: Borrowed ("+") , suffix : alloc :: borrow :: Cow :: Borrowed ("") , } , decimal_separator : alloc :: borrow :: Cow :: Borrowed (".") , grouping_separator : alloc :: borrow :: Cow :: Borrowed (",") , grouping_sizes : icu::decimal :: provider :: GroupingSizesV1 { primary : 3u8 , secondary : 2u8 , min_grouping : 1u8 , } , digits : ['༠' , '༡' , '༢' , '༣' , '༤' , '༥' , '༦' , '༧' , '༨' , '༩'] , } ; static CCP : < icu::decimal :: provider :: DecimalSymbolsV1Marker as icu_provider :: DataMarker > :: Yokeable = icu::decimal :: provider :: DecimalSymbolsV1 { minus_sign_affixes : icu::decimal :: provider :: AffixesV1 { prefix : alloc :: borrow :: Cow :: Borrowed ("-") , suffix : alloc :: borrow :: Cow :: Borrowed ("") , } , plus_sign_affixes : icu::decimal :: provider :: AffixesV1 { prefix : alloc :: borrow :: Cow :: Borrowed ("+") , suffix : alloc :: borrow :: Cow :: Borrowed ("") , } , decimal_separator : alloc :: borrow :: Cow :: Borrowed (".") , grouping_separator : alloc :: borrow :: Cow :: Borrowed (",") , grouping_sizes : icu::decimal :: provider :: GroupingSizesV1 { primary : 3u8 , secondary : 2u8 , min_grouping : 1u8 , } , digits : ['𑄶' , '𑄷' , '𑄸' , '𑄹' , '𑄺' , '𑄻' , '𑄼' , '𑄽' , '𑄾' , '𑄿'] , } ; static AA : < icu::decimal :: provider :: DecimalSymbolsV1Marker as icu_provider :: DataMarker > :: Yokeable = icu::decimal :: provider :: DecimalSymbolsV1 { minus_sign_affixes : icu::decimal :: provider :: AffixesV1 { prefix : alloc :: borrow :: Cow :: Borrowed ("-") , suffix : alloc :: borrow :: Cow :: Borrowed ("") , } , plus_sign_affixes : icu::decimal :: provider :: AffixesV1 { prefix : alloc :: borrow :: Cow :: Borrowed ("+") , suffix : alloc :: borrow :: Cow :: Borrowed ("") , } , decimal_separator : alloc :: borrow :: Cow :: Borrowed (".") , grouping_separator : alloc :: borrow :: Cow :: Borrowed (",") , grouping_sizes : icu::decimal :: provider :: GroupingSizesV1 { primary : 3u8 , secondary : 3u8 , min_grouping : 1u8 , } , digits : ['0' , '1' , '2' , '3' , '4' , '5' , '6' , '7' , '8' , '9'] , } ; static BM_NKOO_U_NU_NKOO : < icu::decimal :: provider :: DecimalSymbolsV1Marker as icu_provider :: DataMarker > :: Yokeable = icu::decimal :: provider :: DecimalSymbolsV1 { minus_sign_affixes : icu::decimal :: provider :: AffixesV1 { prefix : alloc :: borrow :: Cow :: Borrowed ("-") , suffix : alloc :: borrow :: Cow :: Borrowed ("") , } , plus_sign_affixes : icu::decimal :: provider :: AffixesV1 { prefix : alloc :: borrow :: Cow :: Borrowed ("+") , suffix : alloc :: borrow :: Cow :: Borrowed ("") , } , decimal_separator : alloc :: borrow :: Cow :: Borrowed (".") , grouping_separator : alloc :: borrow :: Cow :: Borrowed (",") , grouping_sizes : icu::decimal :: provider :: GroupingSizesV1 { primary : 3u8 , secondary : 3u8 , min_grouping : 1u8 , } , digits : ['߀' , '߁' , '߂' , '߃' , '߄' , '߅' , '߆' , '߇' , '߈' , '߉'] , } ; static BGC : < icu::decimal :: provider :: DecimalSymbolsV1Marker as icu_provider :: DataMarker > :: Yokeable = icu::decimal :: provider :: DecimalSymbolsV1 { minus_sign_affixes : icu::decimal :: provider :: AffixesV1 { prefix : alloc :: borrow :: Cow :: Borrowed ("-") , suffix : alloc :: borrow :: Cow :: Borrowed ("") , } , plus_sign_affixes : icu::decimal :: provider :: AffixesV1 { prefix : alloc :: borrow :: Cow :: Borrowed ("+") , suffix : alloc :: borrow :: Cow :: Borrowed ("") , } , decimal_separator : alloc :: borrow :: Cow :: Borrowed (".") , grouping_separator : alloc :: borrow :: Cow :: Borrowed (",") , grouping_sizes : icu::decimal :: provider :: GroupingSizesV1 { primary : 3u8 , secondary : 3u8 , min_grouping : 1u8 , } , digits : ['०' , '१' , '२' , '३' , '४' , '५' , '६' , '७' , '८' , '९'] , } ; static MNI : < icu::decimal :: provider :: DecimalSymbolsV1Marker as icu_provider :: DataMarker > :: Yokeable = icu::decimal :: provider :: DecimalSymbolsV1 { minus_sign_affixes : icu::decimal :: provider :: AffixesV1 { prefix : alloc :: borrow :: Cow :: Borrowed ("-") , suffix : alloc :: borrow :: Cow :: Borrowed ("") , } , plus_sign_affixes : icu::decimal :: provider :: AffixesV1 { prefix : alloc :: borrow :: Cow :: Borrowed ("+") , suffix : alloc :: borrow :: Cow :: Borrowed ("") , } , decimal_separator : alloc :: borrow :: Cow :: Borrowed (".") , grouping_separator : alloc :: borrow :: Cow :: Borrowed (",") , grouping_sizes : icu::decimal :: provider :: GroupingSizesV1 { primary : 3u8 , secondary : 3u8 , min_grouping : 1u8 , } , digits : ['০' , '১' , '২' , '৩' , '৪' , '৫' , '৬' , '৭' , '৮' , '৯'] , } ; static TA_MY_U_NU_TAMLDEC : < icu::decimal :: provider :: DecimalSymbolsV1Marker as icu_provider :: DataMarker > :: Yokeable = icu::decimal :: provider :: DecimalSymbolsV1 { minus_sign_affixes : icu::decimal :: provider :: AffixesV1 { prefix : alloc :: borrow :: Cow :: Borrowed ("-") , suffix : alloc :: borrow :: Cow :: Borrowed ("") , } , plus_sign_affixes : icu::decimal :: provider :: AffixesV1 { prefix : alloc :: borrow :: Cow :: Borrowed ("+") , suffix : alloc :: borrow :: Cow :: Borrowed ("") , } , decimal_separator : alloc :: borrow :: Cow :: Borrowed (".") , grouping_separator : alloc :: borrow :: Cow :: Borrowed (",") , grouping_sizes : icu::decimal :: provider :: GroupingSizesV1 { primary : 3u8 , secondary : 3u8 , min_grouping : 1u8 , } , digits : ['௦' , '௧' , '௨' , '௩' , '௪' , '௫' , '௬' , '௭' , '௮' , '௯'] , } ; static TE_U_NU_TELU : < icu::decimal :: provider :: DecimalSymbolsV1Marker as icu_provider :: DataMarker > :: Yokeable = icu::decimal :: provider :: DecimalSymbolsV1 { minus_sign_affixes : icu::decimal :: provider :: AffixesV1 { prefix : alloc :: borrow :: Cow :: Borrowed ("-") , suffix : alloc :: borrow :: Cow :: Borrowed ("") , } , plus_sign_affixes : icu::decimal :: provider :: AffixesV1 { prefix : alloc :: borrow :: Cow :: Borrowed ("+") , suffix : alloc :: borrow :: Cow :: Borrowed ("") , } , decimal_separator : alloc :: borrow :: Cow :: Borrowed (".") , grouping_separator : alloc :: borrow :: Cow :: Borrowed (",") , grouping_sizes : icu::decimal :: provider :: GroupingSizesV1 { primary : 3u8 , secondary : 3u8 , min_grouping : 1u8 , } , digits : ['౦' , '౧' , '౨' , '౩' , '౪' , '౫' , '౬' , '౭' , '౮' , '౯'] , } ; static KN_U_NU_KNDA : < icu::decimal :: provider :: DecimalSymbolsV1Marker as icu_provider :: DataMarker > :: Yokeable = icu::decimal :: provider :: DecimalSymbolsV1 { minus_sign_affixes : icu::decimal :: provider :: AffixesV1 { prefix : alloc :: borrow :: Cow :: Borrowed ("-") , suffix : alloc :: borrow :: Cow :: Borrowed ("") , } , plus_sign_affixes : icu::decimal :: provider :: AffixesV1 { prefix : alloc :: borrow :: Cow :: Borrowed ("+") , suffix : alloc :: borrow :: Cow :: Borrowed ("") , } , decimal_separator : alloc :: borrow :: Cow :: Borrowed (".") , grouping_separator : alloc :: borrow :: Cow :: Borrowed (",") , grouping_sizes : icu::decimal :: provider :: GroupingSizesV1 { primary : 3u8 , secondary : 3u8 , min_grouping : 1u8 , } , digits : ['೦' , '೧' , '೨' , '೩' , '೪' , '೫' , '೬' , '೭' , '೮' , '೯'] , } ; static TH_U_NU_THAI : < icu::decimal :: provider :: DecimalSymbolsV1Marker as icu_provider :: DataMarker > :: Yokeable = icu::decimal :: provider :: DecimalSymbolsV1 { minus_sign_affixes : icu::decimal :: provider :: AffixesV1 { prefix : alloc :: borrow :: Cow :: Borrowed ("-") , suffix : alloc :: borrow :: Cow :: Borrowed ("") , } , plus_sign_affixes : icu::decimal :: provider :: AffixesV1 { prefix : alloc :: borrow :: Cow :: Borrowed ("+") , suffix : alloc :: borrow :: Cow :: Borrowed ("") , } , decimal_separator : alloc :: borrow :: Cow :: Borrowed (".") , grouping_separator : alloc :: borrow :: Cow :: Borrowed (",") , grouping_sizes : icu::decimal :: provider :: GroupingSizesV1 { primary : 3u8 , secondary : 3u8 , min_grouping : 1u8 , } , digits : ['๐' , '๑' , '๒' , '๓' , '๔' , '๕' , '๖' , '๗' , '๘' , '๙'] , } ; static BO_IN_U_NU_TIBT : < icu::decimal :: provider :: DecimalSymbolsV1Marker as icu_provider :: DataMarker > :: Yokeable = icu::decimal :: provider :: DecimalSymbolsV1 { minus_sign_affixes : icu::decimal :: provider :: AffixesV1 { prefix : alloc :: borrow :: Cow :: Borrowed ("-") , suffix : alloc :: borrow :: Cow :: Borrowed ("") , } , plus_sign_affixes : icu::decimal :: provider :: AffixesV1 { prefix : alloc :: borrow :: Cow :: Borrowed ("+") , suffix : alloc :: borrow :: Cow :: Borrowed ("") , } , decimal_separator : alloc :: borrow :: Cow :: Borrowed (".") , grouping_separator : alloc :: borrow :: Cow :: Borrowed (",") , grouping_sizes : icu::decimal :: provider :: GroupingSizesV1 { primary : 3u8 , secondary : 3u8 , min_grouping : 1u8 , } , digits : ['༠' , '༡' , '༢' , '༣' , '༤' , '༥' , '༦' , '༧' , '༨' , '༩'] , } ; static MY : < icu::decimal :: provider :: DecimalSymbolsV1Marker as icu_provider :: DataMarker > :: Yokeable = icu::decimal :: provider :: DecimalSymbolsV1 { minus_sign_affixes : icu::decimal :: provider :: AffixesV1 { prefix : alloc :: borrow :: Cow :: Borrowed ("-") , suffix : alloc :: borrow :: Cow :: Borrowed ("") , } , plus_sign_affixes : icu::decimal :: provider :: AffixesV1 { prefix : alloc :: borrow :: Cow :: Borrowed ("+") , suffix : alloc :: borrow :: Cow :: Borrowed ("") , } , decimal_separator : alloc :: borrow :: Cow :: Borrowed (".") , grouping_separator : alloc :: borrow :: Cow :: Borrowed (",") , grouping_sizes : icu::decimal :: provider :: GroupingSizesV1 { primary : 3u8 , secondary : 3u8 , min_grouping : 1u8 , } , digits : ['၀' , '၁' , '၂' , '၃' , '၄' , '၅' , '၆' , '၇' , '၈' , '၉'] , } ; static MN_MONG_U_NU_MONG : < icu::decimal :: provider :: DecimalSymbolsV1Marker as icu_provider :: DataMarker > :: Yokeable = icu::decimal :: provider :: DecimalSymbolsV1 { minus_sign_affixes : icu::decimal :: provider :: AffixesV1 { prefix : alloc :: borrow :: Cow :: Borrowed ("-") , suffix : alloc :: borrow :: Cow :: Borrowed ("") , } , plus_sign_affixes : icu::decimal :: provider :: AffixesV1 { prefix : alloc :: borrow :: Cow :: Borrowed ("+") , suffix : alloc :: borrow :: Cow :: Borrowed ("") , } , decimal_separator : alloc :: borrow :: Cow :: Borrowed (".") , grouping_separator : alloc :: borrow :: Cow :: Borrowed (",") , grouping_sizes : icu::decimal :: provider :: GroupingSizesV1 { primary : 3u8 , secondary : 3u8 , min_grouping : 1u8 , } , digits : ['᠐' , '᠑' , '᠒' , '᠓' , '᠔' , '᠕' , '᠖' , '᠗' , '᠘' , '᠙'] , } ; static SAT : < icu::decimal :: provider :: DecimalSymbolsV1Marker as icu_provider :: DataMarker > :: Yokeable = icu::decimal :: provider :: DecimalSymbolsV1 { minus_sign_affixes : icu::decimal :: provider :: AffixesV1 { prefix : alloc :: borrow :: Cow :: Borrowed ("-") , suffix : alloc :: borrow :: Cow :: Borrowed ("") , } , plus_sign_affixes : icu::decimal :: provider :: AffixesV1 { prefix : alloc :: borrow :: Cow :: Borrowed ("+") , suffix : alloc :: borrow :: Cow :: Borrowed ("") , } , decimal_separator : alloc :: borrow :: Cow :: Borrowed (".") , grouping_separator : alloc :: borrow :: Cow :: Borrowed (",") , grouping_sizes : icu::decimal :: provider :: GroupingSizesV1 { primary : 3u8 , secondary : 3u8 , min_grouping : 1u8 , } , digits : ['᱐' , '᱑' , '᱒' , '᱓' , '᱔' , '᱕' , '᱖' , '᱗' , '᱘' , '᱙'] , } ; static YUE_HANS_U_NU_HANIDEC : < icu::decimal :: provider :: DecimalSymbolsV1Marker as icu_provider :: DataMarker > :: Yokeable = icu::decimal :: provider :: DecimalSymbolsV1 { minus_sign_affixes : icu::decimal :: provider :: AffixesV1 { prefix : alloc :: borrow :: Cow :: Borrowed ("-") , suffix : alloc :: borrow :: Cow :: Borrowed ("") , } , plus_sign_affixes : icu::decimal :: provider :: AffixesV1 { prefix : alloc :: borrow :: Cow :: Borrowed ("+") , suffix : alloc :: borrow :: Cow :: Borrowed ("") , } , decimal_separator : alloc :: borrow :: Cow :: Borrowed (".") , grouping_separator : alloc :: borrow :: Cow :: Borrowed (",") , grouping_sizes : icu::decimal :: provider :: GroupingSizesV1 { primary : 3u8 , secondary : 3u8 , min_grouping : 1u8 , } , digits : ['〇' , '一' , '二' , '三' , '四' , '五' , '六' , '七' , '八' , '九'] , } ; static VAI_VAII_U_NU_VAII : < icu::decimal :: provider :: DecimalSymbolsV1Marker as icu_provider :: DataMarker > :: Yokeable = icu::decimal :: provider :: DecimalSymbolsV1 { minus_sign_affixes : icu::decimal :: provider :: AffixesV1 { prefix : alloc :: borrow :: Cow :: Borrowed ("-") , suffix : alloc :: borrow :: Cow :: Borrowed ("") , } , plus_sign_affixes : icu::decimal :: provider :: AffixesV1 { prefix : alloc :: borrow :: Cow :: Borrowed ("+") , suffix : alloc :: borrow :: Cow :: Borrowed ("") , } , decimal_separator : alloc :: borrow :: Cow :: Borrowed (".") , grouping_separator : alloc :: borrow :: Cow :: Borrowed (",") , grouping_sizes : icu::decimal :: provider :: GroupingSizesV1 { primary : 3u8 , secondary : 3u8 , min_grouping : 1u8 , } , digits : ['꘠' , '꘡' , '꘢' , '꘣' , '꘤' , '꘥' , '꘦' , '꘧' , '꘨' , '꘩'] , } ; static MNI_MTEI : < icu::decimal :: provider :: DecimalSymbolsV1Marker as icu_provider :: DataMarker > :: Yokeable = icu::decimal :: provider :: DecimalSymbolsV1 { minus_sign_affixes : icu::decimal :: provider :: AffixesV1 { prefix : alloc :: borrow :: Cow :: Borrowed ("-") , suffix : alloc :: borrow :: Cow :: Borrowed ("") , } , plus_sign_affixes : icu::decimal :: provider :: AffixesV1 { prefix : alloc :: borrow :: Cow :: Borrowed ("+") , suffix : alloc :: borrow :: Cow :: Borrowed ("") , } , decimal_separator : alloc :: borrow :: Cow :: Borrowed (".") , grouping_separator : alloc :: borrow :: Cow :: Borrowed (",") , grouping_sizes : icu::decimal :: provider :: GroupingSizesV1 { primary : 3u8 , secondary : 3u8 , min_grouping : 1u8 , } , digits : ['꯰' , '꯱' , '꯲' , '꯳' , '꯴' , '꯵' , '꯶' , '꯷' , '꯸' , '꯹'] , } ; static HNJ : < icu::decimal :: provider :: DecimalSymbolsV1Marker as icu_provider :: DataMarker > :: Yokeable = icu::decimal :: provider :: DecimalSymbolsV1 { minus_sign_affixes : icu::decimal :: provider :: AffixesV1 { prefix : alloc :: borrow :: Cow :: Borrowed ("-") , suffix : alloc :: borrow :: Cow :: Borrowed ("") , } , plus_sign_affixes : icu::decimal :: provider :: AffixesV1 { prefix : alloc :: borrow :: Cow :: Borrowed ("+") , suffix : alloc :: borrow :: Cow :: Borrowed ("") , } , decimal_separator : alloc :: borrow :: Cow :: Borrowed (".") , grouping_separator : alloc :: borrow :: Cow :: Borrowed (",") , grouping_sizes : icu::decimal :: provider :: GroupingSizesV1 { primary : 3u8 , secondary : 3u8 , min_grouping : 1u8 , } , digits : ['𞅀' , '𞅁' , '𞅂' , '𞅃' , '𞅄' , '𞅅' , '𞅆' , '𞅇' , '𞅈' , '𞅉'] , } ; static EE : < icu::decimal :: provider :: DecimalSymbolsV1Marker as icu_provider :: DataMarker > :: Yokeable = icu::decimal :: provider :: DecimalSymbolsV1 { minus_sign_affixes : icu::decimal :: provider :: AffixesV1 { prefix : alloc :: borrow :: Cow :: Borrowed ("-") , suffix : alloc :: borrow :: Cow :: Borrowed ("") , } , plus_sign_affixes : icu::decimal :: provider :: AffixesV1 { prefix : alloc :: borrow :: Cow :: Borrowed ("+") , suffix : alloc :: borrow :: Cow :: Borrowed ("") , } , decimal_separator : alloc :: borrow :: Cow :: Borrowed (".") , grouping_separator : alloc :: borrow :: Cow :: Borrowed (",") , grouping_sizes : icu::decimal :: provider :: GroupingSizesV1 { primary : 3u8 , secondary : 3u8 , min_grouping : 3u8 , } , digits : ['0' , '1' , '2' , '3' , '4' , '5' , '6' , '7' , '8' , '9'] , } ; static DJE : < icu::decimal :: provider :: DecimalSymbolsV1Marker as icu_provider :: DataMarker > :: Yokeable = icu::decimal :: provider :: DecimalSymbolsV1 { minus_sign_affixes : icu::decimal :: provider :: AffixesV1 { prefix : alloc :: borrow :: Cow :: Borrowed ("-") , suffix : alloc :: borrow :: Cow :: Borrowed ("") , } , plus_sign_affixes : icu::decimal :: provider :: AffixesV1 { prefix : alloc :: borrow :: Cow :: Borrowed ("+") , suffix : alloc :: borrow :: Cow :: Borrowed ("") , } , decimal_separator : alloc :: borrow :: Cow :: Borrowed (".") , grouping_separator : alloc :: borrow :: Cow :: Borrowed ("\u{a0}") , grouping_sizes : icu::decimal :: provider :: GroupingSizesV1 { primary : 3u8 , secondary : 3u8 , min_grouping : 1u8 , } , digits : ['0' , '1' , '2' , '3' , '4' , '5' , '6' , '7' , '8' , '9'] , } ; static KS_U_NU_LATN : < icu::decimal :: provider :: DecimalSymbolsV1Marker as icu_provider :: DataMarker > :: Yokeable = icu::decimal :: provider :: DecimalSymbolsV1 { minus_sign_affixes : icu::decimal :: provider :: AffixesV1 { prefix : alloc :: borrow :: Cow :: Borrowed ("-") , suffix : alloc :: borrow :: Cow :: Borrowed ("") , } , plus_sign_affixes : icu::decimal :: provider :: AffixesV1 { prefix : alloc :: borrow :: Cow :: Borrowed ("+") , suffix : alloc :: borrow :: Cow :: Borrowed ("") , } , decimal_separator : alloc :: borrow :: Cow :: Borrowed (".") , grouping_separator : alloc :: borrow :: Cow :: Borrowed ("،") , grouping_sizes : icu::decimal :: provider :: GroupingSizesV1 { primary : 3u8 , secondary : 3u8 , min_grouping : 1u8 , } , digits : ['0' , '1' , '2' , '3' , '4' , '5' , '6' , '7' , '8' , '9'] , } ; static NQO : < icu::decimal :: provider :: DecimalSymbolsV1Marker as icu_provider :: DataMarker > :: Yokeable = icu::decimal :: provider :: DecimalSymbolsV1 { minus_sign_affixes : icu::decimal :: provider :: AffixesV1 { prefix : alloc :: borrow :: Cow :: Borrowed ("-") , suffix : alloc :: borrow :: Cow :: Borrowed ("") , } , plus_sign_affixes : icu::decimal :: provider :: AffixesV1 { prefix : alloc :: borrow :: Cow :: Borrowed ("+") , suffix : alloc :: borrow :: Cow :: Borrowed ("") , } , decimal_separator : alloc :: borrow :: Cow :: Borrowed (".") , grouping_separator : alloc :: borrow :: Cow :: Borrowed ("،") , grouping_sizes : icu::decimal :: provider :: GroupingSizesV1 { primary : 3u8 , secondary : 3u8 , min_grouping : 1u8 , } , digits : ['߀' , '߁' , '߂' , '߃' , '߄' , '߅' , '߆' , '߇' , '߈' , '߉'] , } ; static DE_CH : < icu::decimal :: provider :: DecimalSymbolsV1Marker as icu_provider :: DataMarker > :: Yokeable = icu::decimal :: provider :: DecimalSymbolsV1 { minus_sign_affixes : icu::decimal :: provider :: AffixesV1 { prefix : alloc :: borrow :: Cow :: Borrowed ("-") , suffix : alloc :: borrow :: Cow :: Borrowed ("") , } , plus_sign_affixes : icu::decimal :: provider :: AffixesV1 { prefix : alloc :: borrow :: Cow :: Borrowed ("+") , suffix : alloc :: borrow :: Cow :: Borrowed ("") , } , decimal_separator : alloc :: borrow :: Cow :: Borrowed (".") , grouping_separator : alloc :: borrow :: Cow :: Borrowed ("’") , grouping_sizes : icu::decimal :: provider :: GroupingSizesV1 { primary : 3u8 , secondary : 3u8 , min_grouping : 1u8 , } , digits : ['0' , '1' , '2' , '3' , '4' , '5' , '6' , '7' , '8' , '9'] , } ; static FF_ADLM_BF_U_NU_LATN : < icu::decimal :: provider :: DecimalSymbolsV1Marker as icu_provider :: DataMarker > :: Yokeable = icu::decimal :: provider :: DecimalSymbolsV1 { minus_sign_affixes : icu::decimal :: provider :: AffixesV1 { prefix : alloc :: borrow :: Cow :: Borrowed ("-") , suffix : alloc :: borrow :: Cow :: Borrowed ("") , } , plus_sign_affixes : icu::decimal :: provider :: AffixesV1 { prefix : alloc :: borrow :: Cow :: Borrowed ("+") , suffix : alloc :: borrow :: Cow :: Borrowed ("") , } , decimal_separator : alloc :: borrow :: Cow :: Borrowed (".") , grouping_separator : alloc :: borrow :: Cow :: Borrowed ("⹁") , grouping_sizes : icu::decimal :: provider :: GroupingSizesV1 { primary : 3u8 , secondary : 3u8 , min_grouping : 1u8 , } , digits : ['0' , '1' , '2' , '3' , '4' , '5' , '6' , '7' , '8' , '9'] , } ; static FF_ADLM : < icu::decimal :: provider :: DecimalSymbolsV1Marker as icu_provider :: DataMarker > :: Yokeable = icu::decimal :: provider :: DecimalSymbolsV1 { minus_sign_affixes : icu::decimal :: provider :: AffixesV1 { prefix : alloc :: borrow :: Cow :: Borrowed ("-") , suffix : alloc :: borrow :: Cow :: Borrowed ("") , } , plus_sign_affixes : icu::decimal :: provider :: AffixesV1 { prefix : alloc :: borrow :: Cow :: Borrowed ("+") , suffix : alloc :: borrow :: Cow :: Borrowed ("") , } , decimal_separator : alloc :: borrow :: Cow :: Borrowed (".") , grouping_separator : alloc :: borrow :: Cow :: Borrowed ("⹁") , grouping_sizes : icu::decimal :: provider :: GroupingSizesV1 { primary : 3u8 , secondary : 3u8 , min_grouping : 1u8 , } , digits : ['𞥐' , '𞥑' , '𞥒' , '𞥓' , '𞥔' , '𞥕' , '𞥖' , '𞥗' , '𞥘' , '𞥙'] , } ; static BGN_AE_U_NU_LATN : < icu::decimal :: provider :: DecimalSymbolsV1Marker as icu_provider :: DataMarker > :: Yokeable = icu::decimal :: provider :: DecimalSymbolsV1 { minus_sign_affixes : icu::decimal :: provider :: AffixesV1 { prefix : alloc :: borrow :: Cow :: Borrowed ("-") , suffix : alloc :: borrow :: Cow :: Borrowed ("") , } , plus_sign_affixes : icu::decimal :: provider :: AffixesV1 { prefix : alloc :: borrow :: Cow :: Borrowed ("+") , suffix : alloc :: borrow :: Cow :: Borrowed ("") , } , decimal_separator : alloc :: borrow :: Cow :: Borrowed ("٫") , grouping_separator : alloc :: borrow :: Cow :: Borrowed ("،") , grouping_sizes : icu::decimal :: provider :: GroupingSizesV1 { primary : 3u8 , secondary : 3u8 , min_grouping : 1u8 , } , digits : ['0' , '1' , '2' , '3' , '4' , '5' , '6' , '7' , '8' , '9'] , } ; static CKB_IR_U_NU_LATN : < icu::decimal :: provider :: DecimalSymbolsV1Marker as icu_provider :: DataMarker > :: Yokeable = icu::decimal :: provider :: DecimalSymbolsV1 { minus_sign_affixes : icu::decimal :: provider :: AffixesV1 { prefix : alloc :: borrow :: Cow :: Borrowed ("-") , suffix : alloc :: borrow :: Cow :: Borrowed ("") , } , plus_sign_affixes : icu::decimal :: provider :: AffixesV1 { prefix : alloc :: borrow :: Cow :: Borrowed ("\u{200e}+") , suffix : alloc :: borrow :: Cow :: Borrowed ("") , } , decimal_separator : alloc :: borrow :: Cow :: Borrowed (".") , grouping_separator : alloc :: borrow :: Cow :: Borrowed (",") , grouping_sizes : icu::decimal :: provider :: GroupingSizesV1 { primary : 3u8 , secondary : 3u8 , min_grouping : 1u8 , } , digits : ['0' , '1' , '2' , '3' , '4' , '5' , '6' , '7' , '8' , '9'] , } ; static AR_DZ : < icu::decimal :: provider :: DecimalSymbolsV1Marker as icu_provider :: DataMarker > :: Yokeable = icu::decimal :: provider :: DecimalSymbolsV1 { minus_sign_affixes : icu::decimal :: provider :: AffixesV1 { prefix : alloc :: borrow :: Cow :: Borrowed ("\u{200e}-") , suffix : alloc :: borrow :: Cow :: Borrowed ("") , } , plus_sign_affixes : icu::decimal :: provider :: AffixesV1 { prefix : alloc :: borrow :: Cow :: Borrowed ("\u{200e}+") , suffix : alloc :: borrow :: Cow :: Borrowed ("") , } , decimal_separator : alloc :: borrow :: Cow :: Borrowed (",") , grouping_separator : alloc :: borrow :: Cow :: Borrowed (".") , grouping_sizes : icu::decimal :: provider :: GroupingSizesV1 { primary : 3u8 , secondary : 3u8 , min_grouping : 1u8 , } , digits : ['0' , '1' , '2' , '3' , '4' , '5' , '6' , '7' , '8' , '9'] , } ; static AR_AE : < icu::decimal :: provider :: DecimalSymbolsV1Marker as icu_provider :: DataMarker > :: Yokeable = icu::decimal :: provider :: DecimalSymbolsV1 { minus_sign_affixes : icu::decimal :: provider :: AffixesV1 { prefix : alloc :: borrow :: Cow :: Borrowed ("\u{200e}-") , suffix : alloc :: borrow :: Cow :: Borrowed ("") , } , plus_sign_affixes : icu::decimal :: provider :: AffixesV1 { prefix : alloc :: borrow :: Cow :: Borrowed ("\u{200e}+") , suffix : alloc :: borrow :: Cow :: Borrowed ("") , } , decimal_separator : alloc :: borrow :: Cow :: Borrowed (".") , grouping_separator : alloc :: borrow :: Cow :: Borrowed (",") , grouping_sizes : icu::decimal :: provider :: GroupingSizesV1 { primary : 3u8 , secondary : 3u8 , min_grouping : 1u8 , } , digits : ['0' , '1' , '2' , '3' , '4' , '5' , '6' , '7' , '8' , '9'] , } ; static AZ_ARAB : < icu::decimal :: provider :: DecimalSymbolsV1Marker as icu_provider :: DataMarker > :: Yokeable = icu::decimal :: provider :: DecimalSymbolsV1 { minus_sign_affixes : icu::decimal :: provider :: AffixesV1 { prefix : alloc :: borrow :: Cow :: Borrowed ("\u{200e}-\u{200e}") , suffix : alloc :: borrow :: Cow :: Borrowed ("") , } , plus_sign_affixes : icu::decimal :: provider :: AffixesV1 { prefix : alloc :: borrow :: Cow :: Borrowed ("\u{200e}+\u{200e}") , suffix : alloc :: borrow :: Cow :: Borrowed ("") , } , decimal_separator : alloc :: borrow :: Cow :: Borrowed ("٫") , grouping_separator : alloc :: borrow :: Cow :: Borrowed ("٬") , grouping_sizes : icu::decimal :: provider :: GroupingSizesV1 { primary : 3u8 , secondary : 3u8 , min_grouping : 1u8 , } , digits : ['۰' , '۱' , '۲' , '۳' , '۴' , '۵' , '۶' , '۷' , '۸' , '۹'] , } ; static PS_PK_U_NU_LATN : < icu::decimal :: provider :: DecimalSymbolsV1Marker as icu_provider :: DataMarker > :: Yokeable = icu::decimal :: provider :: DecimalSymbolsV1 { minus_sign_affixes : icu::decimal :: provider :: AffixesV1 { prefix : alloc :: borrow :: Cow :: Borrowed ("\u{200e}−") , suffix : alloc :: borrow :: Cow :: Borrowed ("") , } , plus_sign_affixes : icu::decimal :: provider :: AffixesV1 { prefix : alloc :: borrow :: Cow :: Borrowed ("\u{200e}+") , suffix : alloc :: borrow :: Cow :: Borrowed ("") , } , decimal_separator : alloc :: borrow :: Cow :: Borrowed (",") , grouping_separator : alloc :: borrow :: Cow :: Borrowed (".") , grouping_sizes : icu::decimal :: provider :: GroupingSizesV1 { primary : 3u8 , secondary : 3u8 , min_grouping : 1u8 , } , digits : ['0' , '1' , '2' , '3' , '4' , '5' , '6' , '7' , '8' , '9'] , } ; static FA_AF_U_NU_LATN : < icu::decimal :: provider :: DecimalSymbolsV1Marker as icu_provider :: DataMarker > :: Yokeable = icu::decimal :: provider :: DecimalSymbolsV1 { minus_sign_affixes : icu::decimal :: provider :: AffixesV1 { prefix : alloc :: borrow :: Cow :: Borrowed ("\u{200e}−") , suffix : alloc :: borrow :: Cow :: Borrowed ("") , } , plus_sign_affixes : icu::decimal :: provider :: AffixesV1 { prefix : alloc :: borrow :: Cow :: Borrowed ("\u{200e}+") , suffix : alloc :: borrow :: Cow :: Borrowed ("") , } , decimal_separator : alloc :: borrow :: Cow :: Borrowed (".") , grouping_separator : alloc :: borrow :: Cow :: Borrowed (",") , grouping_sizes : icu::decimal :: provider :: GroupingSizesV1 { primary : 3u8 , secondary : 3u8 , min_grouping : 1u8 , } , digits : ['0' , '1' , '2' , '3' , '4' , '5' , '6' , '7' , '8' , '9'] , } ; static FA : < icu::decimal :: provider :: DecimalSymbolsV1Marker as icu_provider :: DataMarker > :: Yokeable = icu::decimal :: provider :: DecimalSymbolsV1 { minus_sign_affixes : icu::decimal :: provider :: AffixesV1 { prefix : alloc :: borrow :: Cow :: Borrowed ("\u{200e}−") , suffix : alloc :: borrow :: Cow :: Borrowed ("") , } , plus_sign_affixes : icu::decimal :: provider :: AffixesV1 { prefix : alloc :: borrow :: Cow :: Borrowed ("\u{200e}+") , suffix : alloc :: borrow :: Cow :: Borrowed ("") , } , decimal_separator : alloc :: borrow :: Cow :: Borrowed ("٫") , grouping_separator : alloc :: borrow :: Cow :: Borrowed ("٬") , grouping_sizes : icu::decimal :: provider :: GroupingSizesV1 { primary : 3u8 , secondary : 3u8 , min_grouping : 1u8 , } , digits : ['۰' , '۱' , '۲' , '۳' , '۴' , '۵' , '۶' , '۷' , '۸' , '۹'] , } ; static CKB : < icu::decimal :: provider :: DecimalSymbolsV1Marker as icu_provider :: DataMarker > :: Yokeable = icu::decimal :: provider :: DecimalSymbolsV1 { minus_sign_affixes : icu::decimal :: provider :: AffixesV1 { prefix : alloc :: borrow :: Cow :: Borrowed ("\u{200f}-") , suffix : alloc :: borrow :: Cow :: Borrowed ("") , } , plus_sign_affixes : icu::decimal :: provider :: AffixesV1 { prefix : alloc :: borrow :: Cow :: Borrowed ("\u{200f}+") , suffix : alloc :: borrow :: Cow :: Borrowed ("") , } , decimal_separator : alloc :: borrow :: Cow :: Borrowed ("٫") , grouping_separator : alloc :: borrow :: Cow :: Borrowed ("٬") , grouping_sizes : icu::decimal :: provider :: GroupingSizesV1 { primary : 3u8 , secondary : 3u8 , min_grouping : 1u8 , } , digits : ['٠' , '١' , '٢' , '٣' , '٤' , '٥' , '٦' , '٧' , '٨' , '٩'] , } ; static AR : < icu::decimal :: provider :: DecimalSymbolsV1Marker as icu_provider :: DataMarker > :: Yokeable = icu::decimal :: provider :: DecimalSymbolsV1 { minus_sign_affixes : icu::decimal :: provider :: AffixesV1 { prefix : alloc :: borrow :: Cow :: Borrowed ("\u{61c}-") , suffix : alloc :: borrow :: Cow :: Borrowed ("") , } , plus_sign_affixes : icu::decimal :: provider :: AffixesV1 { prefix : alloc :: borrow :: Cow :: Borrowed ("\u{61c}+") , suffix : alloc :: borrow :: Cow :: Borrowed ("") , } , decimal_separator : alloc :: borrow :: Cow :: Borrowed ("٫") , grouping_separator : alloc :: borrow :: Cow :: Borrowed ("٬") , grouping_sizes : icu::decimal :: provider :: GroupingSizesV1 { primary : 3u8 , secondary : 3u8 , min_grouping : 1u8 , } , digits : ['٠' , '١' , '٢' , '٣' , '٤' , '٥' , '٦' , '٧' , '٨' , '٩'] , } ; static EU : < icu::decimal :: provider :: DecimalSymbolsV1Marker as icu_provider :: DataMarker > :: Yokeable = icu::decimal :: provider :: DecimalSymbolsV1 { minus_sign_affixes : icu::decimal :: provider :: AffixesV1 { prefix : alloc :: borrow :: Cow :: Borrowed ("−") , suffix : alloc :: borrow :: Cow :: Borrowed ("") , } , plus_sign_affixes : icu::decimal :: provider :: AffixesV1 { prefix : alloc :: borrow :: Cow :: Borrowed ("+") , suffix : alloc :: borrow :: Cow :: Borrowed ("") , } , decimal_separator : alloc :: borrow :: Cow :: Borrowed (",") , grouping_separator : alloc :: borrow :: Cow :: Borrowed (".") , grouping_sizes : icu::decimal :: provider :: GroupingSizesV1 { primary : 3u8 , secondary : 3u8 , min_grouping : 1u8 , } , digits : ['0' , '1' , '2' , '3' , '4' , '5' , '6' , '7' , '8' , '9'] , } ; static FI : < icu::decimal :: provider :: DecimalSymbolsV1Marker as icu_provider :: DataMarker > :: Yokeable = icu::decimal :: provider :: DecimalSymbolsV1 { minus_sign_affixes : icu::decimal :: provider :: AffixesV1 { prefix : alloc :: borrow :: Cow :: Borrowed ("−") , suffix : alloc :: borrow :: Cow :: Borrowed ("") , } , plus_sign_affixes : icu::decimal :: provider :: AffixesV1 { prefix : alloc :: borrow :: Cow :: Borrowed ("+") , suffix : alloc :: borrow :: Cow :: Borrowed ("") , } , decimal_separator : alloc :: borrow :: Cow :: Borrowed (",") , grouping_separator : alloc :: borrow :: Cow :: Borrowed ("\u{a0}") , grouping_sizes : icu::decimal :: provider :: GroupingSizesV1 { primary : 3u8 , secondary : 3u8 , min_grouping : 1u8 , } , digits : ['0' , '1' , '2' , '3' , '4' , '5' , '6' , '7' , '8' , '9'] , } ; static ET : < icu::decimal :: provider :: DecimalSymbolsV1Marker as icu_provider :: DataMarker > :: Yokeable = icu::decimal :: provider :: DecimalSymbolsV1 { minus_sign_affixes : icu::decimal :: provider :: AffixesV1 { prefix : alloc :: borrow :: Cow :: Borrowed ("−") , suffix : alloc :: borrow :: Cow :: Borrowed ("") , } , plus_sign_affixes : icu::decimal :: provider :: AffixesV1 { prefix : alloc :: borrow :: Cow :: Borrowed ("+") , suffix : alloc :: borrow :: Cow :: Borrowed ("") , } , decimal_separator : alloc :: borrow :: Cow :: Borrowed (",") , grouping_separator : alloc :: borrow :: Cow :: Borrowed ("\u{a0}") , grouping_sizes : icu::decimal :: provider :: GroupingSizesV1 { primary : 3u8 , secondary : 3u8 , min_grouping : 2u8 , } , digits : ['0' , '1' , '2' , '3' , '4' , '5' , '6' , '7' , '8' , '9'] , } ; static GSW : < icu::decimal :: provider :: DecimalSymbolsV1Marker as icu_provider :: DataMarker > :: Yokeable = icu::decimal :: provider :: DecimalSymbolsV1 { minus_sign_affixes : icu::decimal :: provider :: AffixesV1 { prefix : alloc :: borrow :: Cow :: Borrowed ("−") , suffix : alloc :: borrow :: Cow :: Borrowed ("") , } , plus_sign_affixes : icu::decimal :: provider :: AffixesV1 { prefix : alloc :: borrow :: Cow :: Borrowed ("+") , suffix : alloc :: borrow :: Cow :: Borrowed ("") , } , decimal_separator : alloc :: borrow :: Cow :: Borrowed (".") , grouping_separator : alloc :: borrow :: Cow :: Borrowed ("’") , grouping_sizes : icu::decimal :: provider :: GroupingSizesV1 { primary : 3u8 , secondary : 3u8 , min_grouping : 1u8 , } , digits : ['0' , '1' , '2' , '3' , '4' , '5' , '6' , '7' , '8' , '9'] , } ; static VALUES : [& < icu::decimal :: provider :: DecimalSymbolsV1Marker as icu_provider :: DataMarker > :: Yokeable ; 821usize] = [& AA , & AA , & AA , & AA , & AF , & AF , & AF , & AA , & AA , & AA , & AA , & AA , & AR , & AR_AE , & AR , & AR , & AR_AE , & AR , & AR_AE , & AR_DZ , & AR , & AR , & AR_AE , & AR_AE , & AR , & AR , & AR_AE , & AR , & AR_AE , & AR , & AR_AE , & AR , & AR_AE , & AR , & AR_AE , & AR , & AR_AE , & AR , & AR_DZ , & AR_DZ , & AR , & AR_DZ , & AR , & AR , & AR_DZ , & AR , & AR_AE , & AR , & AR_AE , & AR , & AR_AE , & AR , & AR_AE , & AR , & AR_AE , & AR , & AR_AE , & AR , & AR_AE , & AR , & AR_AE , & AR , & AR_AE , & AR_DZ , & AR , & AR , & AR_AE , & AR_AE , & AA , & AS , & AS_U_NU_LATN , & AA , & AST , & AST , & AZ_ARAB , & AZ_ARAB , & AA , & AA , & AST , & AZ_ARAB , & AA , & AA , & AA , & AA , & AF , & BE , & BE , & AA , & AA , & AA , & BE , & BGC , & AA , & AZ_ARAB , & AZ_ARAB , & BGN_AE_U_NU_LATN , & AZ_ARAB , & BGN_AE_U_NU_LATN , & AZ_ARAB , & BGN_AE_U_NU_LATN , & AZ_ARAB , & BGN_AE_U_NU_LATN , & BGN_AE_U_NU_LATN , & BGC , & AA , & AF , & AA , & AA , & AA , & BM_NKOO_U_NU_NKOO , & AS , & AS , & AS_U_NU_LATN , & AS_U_NU_LATN , & AA , & AA , & BO_IN_U_NU_TIBT , & BO_IN_U_NU_TIBT , & AF , & AS_U_NU_LATN , & BRX_U_NU_DEVA , & AST , & AST , & AA , & AA , & AST , & AST , & AST , & AST , & AST , & AA , & AA , & CCP , & CCP , & AS_U_NU_LATN , & AS_U_NU_LATN , & AA , & AA , & AA , & AA , & AA , & AA , & CKB , & CKB , & CKB_IR_U_NU_LATN , & CKB_IR_U_NU_LATN , & AA , & AF , & AA , & AA , & AF , & AA , & AST , & AST , & AA , & AST , & AF , & AST , & DE_CH , & AST , & DE_CH , & AST , & DJE , & AA , & BGC , & AST , & AF , & AA , & AR , & AF , & DZ , & AS_U_NU_LATN , & AA , & EE , & EE , & AST , & AST , & AST , & AA , & AA , & AA , & AA , & AA , & AA , & AA , & AST , & AA , & AA , & AST , & AA , & AA , & AA , & AA , & AA , & AA , & AA , & DE_CH , & AA , & AA , & AA , & AA , & AST , & AA , & AST , & AA , & AA , & AA , & AF , & AA , & AA , & AA , & AA , & AA , & AA , & AA , & AA , & AA , & AA , & AA , & AA , & AST , & AA , & AA , & AA , & AS_U_NU_LATN , & AA , & AA , & AA , & AA , & AA , & AA , & AA , & AA , & AA , & AA , & AA , & AA , & AA , & AA , & AA , & AA , & AA , & AA , & AA , & AA , & AA , & AA , & AA , & AST , & AA , & AA , & AA , & AA , & AA , & AA , & AA , & AA , & AA , & AA , & AA , & AA , & AA , & AF , & AA , & AA , & AST , & AA , & AA , & AA , & AA , & AA , & AA , & AA , & AA , & AA , & AA , & AA , & AA , & AA , & AA , & AA , & AA , & AA , & AA , & AA , & AA , & AA , & AF , & ES , & AA , & AST , & AST , & AA , & AA , & AST , & AST , & AF , & AA , & AA , & ES , & AST , & ES , & AA , & AA , & ES , & AA , & AA , & AA , & AA , & ES , & AA , & AST , & AA , & AA , & AST , & AST , & ET , & EU , & AF , & FA , & FA , & FA_AF_U_NU_LATN , & FA_AF_U_NU_LATN , & AF , & FF_ADLM , & FF_ADLM , & FF_ADLM_BF_U_NU_LATN , & FF_ADLM , & FF_ADLM_BF_U_NU_LATN , & FF_ADLM , & FF_ADLM_BF_U_NU_LATN , & FF_ADLM , & FF_ADLM_BF_U_NU_LATN , & FF_ADLM , & FF_ADLM_BF_U_NU_LATN , & FF_ADLM , & FF_ADLM_BF_U_NU_LATN , & FF_ADLM , & FF_ADLM_BF_U_NU_LATN , & FF_ADLM , & FF_ADLM_BF_U_NU_LATN , & FF_ADLM , & FF_ADLM_BF_U_NU_LATN , & FF_ADLM , & FF_ADLM_BF_U_NU_LATN , & FF_ADLM , & FF_ADLM_BF_U_NU_LATN , & FF_ADLM_BF_U_NU_LATN , & AF , & AF , & AF , & AF , & AF , & AF , & AF , & AF , & AF , & AF , & AF , & FI , & AA , & EU , & EU , & FR , & FR , & FR , & FR , & FR , & FR , & AF , & FR , & FR , & FR , & FR , & FR , & FR , & FR , & FR , & FR , & FR , & FR , & FR , & FR , & FR , & FR , & AST , & AST , & FR , & FR , & FR , & FR , & FR , & FR , & FR , & FR , & FR , & FR , & FR , & FR , & FR , & FR , & FR , & FR , & FR , & FR , & FR , & FR , & FR , & FR , & AA , & AST , & AST , & AA , & AA , & AA , & AA , & AA , & AA , & AST , & AA , & GSW , & GSW , & GSW , & AS_U_NU_LATN , & GU_U_NU_GUJR , & AA , & AA , & AA , & AA , & AR , & AA , & AA , & AA , & AR , & AA , & AR_AE , & AS_U_NU_LATN , & AS_U_NU_LATN , & BRX_U_NU_DEVA , & HNJ , & HNJ , & AA , & AA , & EU , & EU , & AST , & BE , & AF , & ES , & AST , & AF , & AA , & AA , & AA , & AST , & AST , & DE_CH , & AST , & AST , & AA , & AA , & AA , & AST , & AA , & AST , & JV_U_NU_JAVA , & BE , & AF , & AA , & AA , & AA , & AA , & AF , & AA , & AST , & DJE , & AA , & AF , & AST , & AST , & AA , & AA , & KM_U_NU_KHMR , & AA , & KN_U_NU_KNDA , & AA , & AA , & AA , & AA , & BGC , & AA , & AA , & AZ_ARAB , & AA , & KS_U_NU_LATN , & AA , & AF , & FI , & AST , & AA , & AS_U_NU_LATN , & AS_U_NU_LATN , & BRX_U_NU_DEVA , & AS_U_NU_LATN , & KXV_ORYA_U_NU_ORYA , & AS_U_NU_LATN , & KXV_TELU_U_NU_TELU , & AF , & AA , & AA , & AST , & AA , & AST , & AA , & LMO , & AST , & AST , & AST , & AST , & AST , & LO_U_NU_LAOO , & AZ_ARAB , & AZ_ARAB , & AA , & AA , & FI , & AST , & AA , & AA , & BE , & AA , & BGC , & AA , & AA , & AA , & AA , & DJE , & AA , & AST , & AA , & AA , & AA , & AST , & AS_U_NU_LATN , & ML_U_NU_MLYM , & AA , & AA , & MN_MONG_MN , & MN_MONG_MN_U_NU_MONG , & MN_MONG_U_NU_MONG , & MNI , & MNI_MTEI , & AA , & AA , & AA , & BRX_U_NU_DEVA , & AS_U_NU_LATN , & AA , & AA , & AST , & AST , & AST , & AA , & AA , & AST , & AA , & MY , & AA , & AA , & AZ_ARAB , & AA , & AA , & FI , & FI , & AA , & AST , & AST , & BRX_U_NU_DEVA , & BRX_U_NU_DEVA , & AS_U_NU_LATN , & AS_U_NU_LATN , & AST , & AST , & AST , & AST , & AST , & AST , & AST , & AF , & FI , & AST , & FI , & NQO , & KS_U_NU_LATN , & AF , & DJE , & AA , & AA , & AA , & AA , & AF , & AF , & AA , & AA , & AS_U_NU_LATN , & KXV_ORYA_U_NU_ORYA , & AF , & AF , & AA , & AS_U_NU_LATN , & AZ_ARAB , & AR_AE , & PA_U_NU_GURU , & AA , & AA , & AA , & AA , & BE , & AF , & AZ_ARAB , & AZ_ARAB , & PS_PK_U_NU_LATN , & PS_PK_U_NU_LATN , & AST , & AF , & BE , & BE , & BE , & BE , & BE , & BE , & BE , & BE , & BE , & BE , & AA , & AST , & AA , & AA , & BGC , & AA , & AA , & AA , & AA , & AA , & GSW , & AST , & AST , & AST , & AA , & AF , & AF , & AF , & AF , & AF , & BE , & AST , & AA , & BRX_U_NU_DEVA , & AS_U_NU_LATN , & AF , & AA , & SAT , & BGC , & AA , & AA , & AA , & AST , & AA , & AR , & AA , & AA , & AR , & AR , & AA , & AA , & FI , & FI , & FI , & AST , & DJE , & AST , & AF , & AF , & AA , & AA , & AA , & AA , & AF , & AA , & EU , & AA , & AA , & AA , & AA , & AF , & AA , & AA , & AA , & AA , & AA , & AA , & BE , & BE , & BE , & AST , & AST , & AST , & AST , & AST , & AST , & AST , & AST , & AF , & AF , & AA , & AF , & AF , & AST , & FI , & FI , & FI , & AA , & AST , & AA , & AA , & AA , & AA , & AF , & AS_U_NU_LATN , & AS_U_NU_LATN , & TA_LK_U_NU_TAMLDEC , & AA , & TA_MY_U_NU_TAMLDEC , & AA , & TA_MY_U_NU_TAMLDEC , & TA_LK_U_NU_TAMLDEC , & AS_U_NU_LATN , & TE_U_NU_TELU , & AA , & AA , & AF , & AA , & TH_U_NU_THAI , & AA , & AA , & AA , & AF , & DJE , & DJE , & AA , & TOK , & AA , & AST , & AST , & AA , & AA , & AF , & AF , & DJE , & AA , & AF , & AA , & AZ_ARAB , & AF , & AA , & AR_AE , & AZ_ARAB , & AR_AE , & AZ_ARAB , & AF , & AZ_ARAB , & PS_PK_U_NU_LATN , & AF , & AA , & AA , & VAI_VAII_U_NU_VAII , & VAI_VAII_U_NU_VAII , & AF , & FR , & AST , & AST , & AA , & AA , & AA , & LMO , & AA , & AA , & AST , & DJE , & AS_U_NU_LATN , & BRX_U_NU_DEVA , & AA , & AF , & AA , & AA , & AA , & AST , & AST , & AST , & AA , & AA , & YUE_HANS_U_NU_HANIDEC , & YUE_HANS_U_NU_HANIDEC , & AA , & AF , & AA , & AA , & YUE_HANS_U_NU_HANIDEC , & AA , & YUE_HANS_U_NU_HANIDEC , & AA , & YUE_HANS_U_NU_HANIDEC , & AA , & YUE_HANS_U_NU_HANIDEC , & AA , & YUE_HANS_U_NU_HANIDEC , & AA , & YUE_HANS_U_NU_HANIDEC , & YUE_HANS_U_NU_HANIDEC , & AA] ; static KEYS : [& str ; 821usize] = ["aa" , "aa-DJ" , "aa-ER" , "ab" , "af" , "af-NA" , "agq" , "ak" , "am" , "an" , "ann" , "apc" , "ar" , "ar-AE" , "ar-AE-u-nu-arab" , "ar-BH" , "ar-BH-u-nu-latn" , "ar-DJ" , "ar-DJ-u-nu-latn" , "ar-DZ" , "ar-DZ-u-nu-arab" , "ar-EG" , "ar-EG-u-nu-latn" , "ar-EH" , "ar-EH-u-nu-arab" , "ar-ER" , "ar-ER-u-nu-latn" , "ar-IL" , "ar-IL-u-nu-latn" , "ar-IQ" , "ar-IQ-u-nu-latn" , "ar-JO" , "ar-JO-u-nu-latn" , "ar-KM" , "ar-KM-u-nu-latn" , "ar-KW" , "ar-KW-u-nu-latn" , "ar-LB" , "ar-LB-u-nu-latn" , "ar-LY" , "ar-LY-u-nu-arab" , "ar-MA" , "ar-MA-u-nu-arab" , "ar-MR" , "ar-MR-u-nu-latn" , "ar-OM" , "ar-OM-u-nu-latn" , "ar-PS" , "ar-PS-u-nu-latn" , "ar-QA" , "ar-QA-u-nu-latn" , "ar-SA" , "ar-SA-u-nu-latn" , "ar-SD" , "ar-SD-u-nu-latn" , "ar-SO" , "ar-SO-u-nu-latn" , "ar-SS" , "ar-SS-u-nu-latn" , "ar-SY" , "ar-SY-u-nu-latn" , "ar-TD" , "ar-TD-u-nu-latn" , "ar-TN" , "ar-TN-u-nu-arab" , "ar-YE" , "ar-YE-u-nu-latn" , "ar-u-nu-latn" , "arn" , "as" , "as-u-nu-latn" , "asa" , "ast" , "az" , "az-Arab" , "az-Arab-TR" , "az-Arab-TR-u-nu-latn" , "az-Arab-u-nu-latn" , "az-Cyrl" , "az-IQ" , "az-IQ-u-nu-latn" , "ba" , "bal" , "bal-Arab" , "bas" , "be" , "be-tarask" , "bem" , "bew" , "bez" , "bg" , "bgc" , "bgc-u-nu-latn" , "bgn" , "bgn-AE" , "bgn-AE-u-nu-latn" , "bgn-AF" , "bgn-AF-u-nu-latn" , "bgn-IR" , "bgn-IR-u-nu-latn" , "bgn-OM" , "bgn-OM-u-nu-latn" , "bgn-u-nu-latn" , "bho" , "bho-u-nu-latn" , "blo" , "blt" , "bm" , "bm-Nkoo" , "bm-Nkoo-u-nu-nkoo" , "bn" , "bn-IN" , "bn-IN-u-nu-latn" , "bn-u-nu-latn" , "bo" , "bo-IN" , "bo-IN-u-nu-tibt" , "bo-u-nu-tibt" , "br" , "brx" , "brx-u-nu-deva" , "bs" , "bs-Cyrl" , "bss" , "byn" , "ca" , "ca-AD" , "ca-ES-valencia" , "ca-FR" , "ca-IT" , "cad" , "cch" , "ccp" , "ccp-IN" , "ccp-IN-u-nu-latn" , "ccp-u-nu-latn" , "ce" , "ceb" , "cgg" , "cho" , "chr" , "cic" , "ckb" , "ckb-IR" , "ckb-IR-u-nu-latn" , "ckb-u-nu-latn" , "co" , "cs" , "csw" , "cu" , "cv" , "cy" , "da" , "da-GL" , "dav" , "de" , "de-AT" , "de-BE" , "de-CH" , "de-IT" , "de-LI" , "de-LU" , "dje" , "doi" , "doi-u-nu-deva" , "dsb" , "dua" , "dv" , "dv-u-nu-arab" , "dyo" , "dz" , "dz-u-nu-latn" , "ebu" , "ee" , "ee-TG" , "el" , "el-CY" , "el-polyton" , "en" , "en-001" , "en-150" , "en-AE" , "en-AG" , "en-AI" , "en-AS" , "en-AT" , "en-AU" , "en-BB" , "en-BE" , "en-BI" , "en-BM" , "en-BS" , "en-BW" , "en-BZ" , "en-CA" , "en-CC" , "en-CH" , "en-CK" , "en-CM" , "en-CX" , "en-CY" , "en-DE" , "en-DG" , "en-DK" , "en-DM" , "en-Dsrt" , "en-ER" , "en-FI" , "en-FJ" , "en-FK" , "en-FM" , "en-GB" , "en-GD" , "en-GG" , "en-GH" , "en-GI" , "en-GM" , "en-GU" , "en-GY" , "en-HK" , "en-ID" , "en-IE" , "en-IL" , "en-IM" , "en-IN" , "en-IO" , "en-JE" , "en-JM" , "en-KE" , "en-KI" , "en-KN" , "en-KY" , "en-LC" , "en-LR" , "en-LS" , "en-MG" , "en-MH" , "en-MO" , "en-MP" , "en-MS" , "en-MT" , "en-MU" , "en-MV" , "en-MW" , "en-MY" , "en-NA" , "en-NF" , "en-NG" , "en-NL" , "en-NR" , "en-NU" , "en-NZ" , "en-PG" , "en-PH" , "en-PK" , "en-PN" , "en-PR" , "en-PW" , "en-RW" , "en-SB" , "en-SC" , "en-SD" , "en-SE" , "en-SG" , "en-SH" , "en-SI" , "en-SL" , "en-SS" , "en-SX" , "en-SZ" , "en-Shaw" , "en-TC" , "en-TK" , "en-TO" , "en-TT" , "en-TV" , "en-TZ" , "en-UG" , "en-UM" , "en-VC" , "en-VG" , "en-VI" , "en-VU" , "en-WS" , "en-ZA" , "en-ZM" , "en-ZW" , "eo" , "es" , "es-419" , "es-AR" , "es-BO" , "es-BR" , "es-BZ" , "es-CL" , "es-CO" , "es-CR" , "es-CU" , "es-DO" , "es-EA" , "es-EC" , "es-GQ" , "es-GT" , "es-HN" , "es-IC" , "es-MX" , "es-NI" , "es-PA" , "es-PE" , "es-PH" , "es-PR" , "es-PY" , "es-SV" , "es-US" , "es-UY" , "es-VE" , "et" , "eu" , "ewo" , "fa" , "fa-AF" , "fa-AF-u-nu-latn" , "fa-u-nu-latn" , "ff" , "ff-Adlm" , "ff-Adlm-BF" , "ff-Adlm-BF-u-nu-latn" , "ff-Adlm-CM" , "ff-Adlm-CM-u-nu-latn" , "ff-Adlm-GH" , "ff-Adlm-GH-u-nu-latn" , "ff-Adlm-GM" , "ff-Adlm-GM-u-nu-latn" , "ff-Adlm-GW" , "ff-Adlm-GW-u-nu-latn" , "ff-Adlm-LR" , "ff-Adlm-LR-u-nu-latn" , "ff-Adlm-MR" , "ff-Adlm-MR-u-nu-latn" , "ff-Adlm-NE" , "ff-Adlm-NE-u-nu-latn" , "ff-Adlm-NG" , "ff-Adlm-NG-u-nu-latn" , "ff-Adlm-SL" , "ff-Adlm-SL-u-nu-latn" , "ff-Adlm-SN" , "ff-Adlm-SN-u-nu-latn" , "ff-Adlm-u-nu-latn" , "ff-BF" , "ff-CM" , "ff-GH" , "ff-GM" , "ff-GN" , "ff-GW" , "ff-LR" , "ff-MR" , "ff-NE" , "ff-NG" , "ff-SL" , "fi" , "fil" , "fo" , "fo-DK" , "fr" , "fr-BE" , "fr-BF" , "fr-BI" , "fr-BJ" , "fr-BL" , "fr-CA" , "fr-CD" , "fr-CF" , "fr-CG" , "fr-CH" , "fr-CI" , "fr-CM" , "fr-DJ" , "fr-DZ" , "fr-GA" , "fr-GF" , "fr-GN" , "fr-GP" , "fr-GQ" , "fr-HT" , "fr-KM" , "fr-LU" , "fr-MA" , "fr-MC" , "fr-MF" , "fr-MG" , "fr-ML" , "fr-MQ" , "fr-MR" , "fr-MU" , "fr-NC" , "fr-NE" , "fr-PF" , "fr-PM" , "fr-RE" , "fr-RW" , "fr-SC" , "fr-SN" , "fr-SY" , "fr-TD" , "fr-TG" , "fr-TN" , "fr-VU" , "fr-WF" , "fr-YT" , "frr" , "fur" , "fy" , "ga" , "ga-GB" , "gaa" , "gd" , "gez" , "gez-ER" , "gl" , "gn" , "gsw" , "gsw-FR" , "gsw-LI" , "gu" , "gu-u-nu-gujr" , "guz" , "gv" , "ha" , "ha-Arab" , "ha-Arab-u-nu-arab" , "ha-GH" , "ha-NE" , "ha-SD" , "ha-SD-u-nu-arab" , "haw" , "he" , "hi" , "hi-Latn" , "hi-u-nu-deva" , "hnj" , "hnj-Hmnp" , "hnj-Hmnp-u-nu-latn" , "hnj-u-nu-latn" , "hr" , "hr-BA" , "hsb" , "hu" , "hy" , "ia" , "id" , "ie" , "ig" , "ii" , "io" , "is" , "it" , "it-CH" , "it-SM" , "it-VA" , "iu" , "ja" , "jbo" , "jgo" , "jmc" , "jv" , "jv-u-nu-java" , "ka" , "kab" , "kaj" , "kam" , "kcg" , "kde" , "kea" , "ken" , "kgp" , "khq" , "ki" , "kk" , "kkj" , "kl" , "kln" , "km" , "km-u-nu-khmr" , "kn" , "kn-u-nu-knda" , "ko" , "ko-CN" , "ko-KP" , "kok" , "kok-u-nu-deva" , "kpe" , "kpe-GN" , "ks" , "ks-Deva" , "ks-u-nu-latn" , "ksb" , "ksf" , "ksh" , "ku" , "kw" , "kxv" , "kxv-Deva" , "kxv-Deva-u-nu-deva" , "kxv-Orya" , "kxv-Orya-u-nu-orya" , "kxv-Telu" , "kxv-Telu-u-nu-telu" , "ky" , "la" , "lag" , "lb" , "lg" , "lij" , "lkt" , "lmo" , "ln" , "ln-AO" , "ln-CF" , "ln-CG" , "lo" , "lo-u-nu-laoo" , "lrc" , "lrc-IQ" , "lrc-IQ-u-nu-latn" , "lrc-u-nu-latn" , "lt" , "lu" , "luo" , "luy" , "lv" , "mai" , "mai-u-nu-deva" , "mas" , "mas-TZ" , "mdf" , "mer" , "mfe" , "mg" , "mgh" , "mgo" , "mi" , "mic" , "mk" , "ml" , "ml-u-nu-mlym" , "mn" , "mn-Mong" , "mn-Mong-MN" , "mn-Mong-MN-u-nu-mong" , "mn-Mong-u-nu-mong" , "mni" , "mni-Mtei" , "mni-Mtei-u-nu-latn" , "mni-u-nu-latn" , "moh" , "mr" , "mr-u-nu-latn" , "ms" , "ms-Arab" , "ms-Arab-BN" , "ms-BN" , "ms-ID" , "ms-SG" , "mt" , "mua" , "mus" , "my" , "my-u-nu-latn" , "myv" , "mzn" , "mzn-u-nu-latn" , "naq" , "nb" , "nb-SJ" , "nd" , "nds" , "nds-NL" , "ne" , "ne-IN" , "ne-IN-u-nu-latn" , "ne-u-nu-latn" , "nl" , "nl-AW" , "nl-BE" , "nl-BQ" , "nl-CW" , "nl-SR" , "nl-SX" , "nmg" , "nn" , "nnh" , "no" , "nqo" , "nqo-u-nu-latn" , "nr" , "nso" , "nus" , "nv" , "ny" , "nyn" , "oc" , "oc-ES" , "om" , "om-KE" , "or" , "or-u-nu-orya" , "os" , "os-RU" , "osa" , "pa" , "pa-Arab" , "pa-Arab-u-nu-latn" , "pa-u-nu-guru" , "pap" , "pap-AW" , "pcm" , "pis" , "pl" , "prg" , "ps" , "ps-PK" , "ps-PK-u-nu-latn" , "ps-u-nu-latn" , "pt" , "pt-AO" , "pt-CH" , "pt-CV" , "pt-GQ" , "pt-GW" , "pt-LU" , "pt-MO" , "pt-MZ" , "pt-PT" , "pt-ST" , "pt-TL" , "qu" , "qu-BO" , "qu-EC" , "quc" , "raj" , "raj-u-nu-latn" , "rhg" , "rhg-Rohg" , "rhg-Rohg-BD" , "rif" , "rm" , "rn" , "ro" , "ro-MD" , "rof" , "ru" , "ru-BY" , "ru-KG" , "ru-KZ" , "ru-MD" , "ru-UA" , "rw" , "rwk" , "sa" , "sa-u-nu-latn" , "sah" , "saq" , "sat" , "sat-Deva" , "sat-Deva-u-nu-latn" , "sat-u-nu-latn" , "sbp" , "sc" , "scn" , "sd" , "sd-Deva" , "sd-u-nu-latn" , "sdh" , "sdh-IQ" , "sdh-IQ-u-nu-latn" , "sdh-u-nu-latn" , "se" , "se-FI" , "se-SE" , "seh" , "ses" , "sg" , "shi" , "shi-Tfng" , "shn" , "shn-TH" , "si" , "sid" , "sk" , "skr" , "sl" , "sma" , "sma-NO" , "smj" , "smj-NO" , "smn" , "sms" , "sn" , "so" , "so-DJ" , "so-ET" , "so-KE" , "sq" , "sq-MK" , "sq-XK" , "sr" , "sr-BA" , "sr-Cyrl-ME" , "sr-Latn" , "sr-Latn-BA" , "sr-Latn-XK" , "sr-ME" , "sr-XK" , "ss" , "ss-SZ" , "ssy" , "st" , "st-LS" , "su" , "sv" , "sv-AX" , "sv-FI" , "sw" , "sw-CD" , "sw-KE" , "sw-UG" , "syr" , "syr-SY" , "szl" , "ta" , "ta-LK" , "ta-LK-u-nu-tamldec" , "ta-MY" , "ta-MY-u-nu-tamldec" , "ta-SG" , "ta-SG-u-nu-tamldec" , "ta-u-nu-tamldec" , "te" , "te-u-nu-telu" , "teo" , "teo-KE" , "tg" , "th" , "th-u-nu-thai" , "ti" , "ti-ER" , "tig" , "tk" , "tn" , "tn-BW" , "to" , "tok" , "tpi" , "tr" , "tr-CY" , "trv" , "trw" , "ts" , "tt" , "twq" , "tyv" , "tzm" , "ug" , "ug-u-nu-arabext" , "uk" , "und" , "ur" , "ur-IN" , "ur-IN-u-nu-latn" , "ur-u-nu-arabext" , "uz" , "uz-Arab" , "uz-Arab-u-nu-latn" , "uz-Cyrl" , "vai" , "vai-Vaii" , "vai-Vaii-u-nu-vaii" , "vai-u-nu-vaii" , "ve" , "vec" , "vi" , "vmw" , "vo" , "vun" , "wa" , "wae" , "wal" , "wbp" , "wo" , "xh" , "xnr" , "xnr-u-nu-deva" , "xog" , "yav" , "yi" , "yo" , "yo-BJ" , "yrl" , "yrl-CO" , "yrl-VE" , "yue" , "yue-Hans" , "yue-Hans-u-nu-hanidec" , "yue-u-nu-hanidec" , "za" , "zgh" , "zh" , "zh-HK" , "zh-HK-u-nu-hanidec" , "zh-Hans-HK" , "zh-Hans-HK-u-nu-hanidec" , "zh-Hans-MO" , "zh-Hans-MO-u-nu-hanidec" , "zh-Hant" , "zh-Hant-u-nu-hanidec" , "zh-MO" , "zh-MO-u-nu-hanidec" , "zh-SG" , "zh-SG-u-nu-hanidec" , "zh-u-nu-hanidec" , "zu"] ; if let Ok (payload) = KEYS . binary_search_by (| k | req . locale . strict_cmp (k . as_bytes ()) . reverse ()) . map (| i | * unsafe { VALUES . get_unchecked (i) }) { Ok (icu_provider :: DataResponse { payload : Some (icu_provider :: DataPayload :: from_static_ref (payload)) , metadata : Default :: default () , }) } else { Err (icu_provider :: DataErrorKind :: MissingLocale . with_req (< icu::decimal :: provider :: DecimalSymbolsV1Marker as icu_provider :: KeyedDataMarker > :: KEY , req)) } } } } } \ No newline at end of file diff --git a/fluent-bundle/src/icu4x_data/mod.rs b/fluent-bundle/src/icu4x_data/mod.rs new file mode 100644 index 00000000..e4653a05 --- /dev/null +++ b/fluent-bundle/src/icu4x_data/mod.rs @@ -0,0 +1,2 @@ +// @generated +include ! ("macros.rs") ; macro_rules ! impl_data_provider { ($ provider : ty) => { make_provider ! ($ provider) ; impl_decimal_symbols_v1 ! ($ provider) ; } ; } # [allow (unused_macros)] macro_rules ! impl_any_provider { ($ provider : ty) => { # [clippy :: msrv = "1.67"] impl icu_provider :: AnyProvider for $ provider { fn load_any (& self , key : icu_provider :: DataKey , req : icu_provider :: DataRequest) -> Result < icu_provider :: AnyResponse , icu_provider :: DataError > { match key . hashed () { h if h == < icu::decimal :: provider :: DecimalSymbolsV1Marker as icu_provider :: KeyedDataMarker > :: KEY . hashed () => icu_provider :: DataProvider :: < icu::decimal :: provider :: DecimalSymbolsV1Marker > :: load (self , req) . map (icu_provider :: DataResponse :: wrap_into_any_response) , _ => Err (icu_provider :: DataErrorKind :: MissingDataKey . with_req (key , req)) , } } } } } # [clippy :: msrv = "1.67"] pub struct BakedDataProvider ; impl_data_provider ! (BakedDataProvider) ; \ No newline at end of file diff --git a/fluent-bundle/src/icu_data_provider.rs b/fluent-bundle/src/icu_data_provider.rs new file mode 100644 index 00000000..c17f95e4 --- /dev/null +++ b/fluent-bundle/src/icu_data_provider.rs @@ -0,0 +1,26 @@ +extern crate alloc; + +// to regerate the icu4x_data module, run from the root of the project: +// cargo build --examples +// rm -r fluent-bundle/src/icu4x_data +// icu4x-datagen --keys-for-bin target/debug/examples/functions --format mod --locales full -o fluent-bundle/src/icu4x_data +// for more information: https://github.com/unicode-org/icu4x/blob/79480dfbafdedf6cc810e4bfb0770f3268ff86ab/tutorials/data_management.md +include!("./icu4x_data/mod.rs"); +impl_any_provider!(BakedDataProvider); + +/// ICU data provider +/// +/// Fluent uses ICU4X data for formatting purposes, like number formatting. +/// Use FluentIcuDataProvider to add all ICU data needed by fluent-bundle. +/// You can bring your own provider if you don't need all locales, or have one in your project already. +/// +/// Example: +/// ``` +/// use fluent_bundle::{FluentBundle, FluentIcuDataProvider, FluentResource}; +/// use unic_langid::langid; +/// +/// let langid = langid!("en-US"); +/// let mut bundle: FluentBundle = FluentBundle::new(vec![langid]); +/// bundle.set_icu_data_provider(Box::new(FluentIcuDataProvider)); +/// ``` +pub use BakedDataProvider as FluentIcuDataProvider; diff --git a/fluent-bundle/src/lib.rs b/fluent-bundle/src/lib.rs index 93d7ea53..19494212 100644 --- a/fluent-bundle/src/lib.rs +++ b/fluent-bundle/src/lib.rs @@ -104,6 +104,7 @@ pub mod bundle; pub mod concurrent; mod entry; mod errors; +mod icu_data_provider; #[doc(hidden)] pub mod memoizer; mod message; @@ -122,6 +123,7 @@ pub use args::FluentArgs; /// [`FluentBundle::new_concurrent`](crate::concurrent::FluentBundle::new_concurrent). pub type FluentBundle = bundle::FluentBundle; pub use errors::FluentError; +pub use icu_data_provider::FluentIcuDataProvider; pub use message::{FluentAttribute, FluentMessage}; pub use resource::FluentResource; #[doc(inline)] diff --git a/fluent-bundle/src/memoizer.rs b/fluent-bundle/src/memoizer.rs index 1f03e308..60d620e8 100644 --- a/fluent-bundle/src/memoizer.rs +++ b/fluent-bundle/src/memoizer.rs @@ -18,7 +18,12 @@ pub trait MemoizerKind: 'static { /// /// `U` - The callback that accepts the instance of the intl formatter, and generates /// some kind of results `R`. - fn with_try_get_threadsafe(&self, args: I::Args, callback: U) -> Result + fn with_try_get_threadsafe( + &self, + args: I::Args, + data_provider: &I::DataProvider, + callback: U, + ) -> Result where Self: Sized, I: Memoizable + Send + Sync + 'static, diff --git a/fluent-bundle/src/types/mod.rs b/fluent-bundle/src/types/mod.rs index 585e90b6..31154f95 100644 --- a/fluent-bundle/src/types/mod.rs +++ b/fluent-bundle/src/types/mod.rs @@ -206,7 +206,7 @@ impl<'source> FluentValue<'source> { scope .bundle .intls - .with_try_get_threadsafe::((r#type,), |pr| { + .with_try_get_threadsafe::((r#type,), &(), |pr| { pr.0.select(b) == Ok(cat) }) .unwrap() @@ -229,7 +229,7 @@ impl<'source> FluentValue<'source> { } match self { FluentValue::String(s) => w.write_str(s), - FluentValue::Number(n) => w.write_str(&n.as_string()), + FluentValue::Number(n) => w.write_str(&n.as_string(scope.bundle)), FluentValue::Custom(s) => w.write_str(&scope.bundle.intls.stringify_value(&**s)), FluentValue::Error => Ok(()), FluentValue::None => Ok(()), @@ -251,7 +251,7 @@ impl<'source> FluentValue<'source> { } match self { FluentValue::String(s) => s.clone(), - FluentValue::Number(n) => n.as_string(), + FluentValue::Number(n) => n.as_string(scope.bundle), FluentValue::Custom(s) => scope.bundle.intls.stringify_value(&**s), FluentValue::Error => "".into(), FluentValue::None => "".into(), @@ -273,7 +273,7 @@ impl<'source> FluentValue<'source> { } match self { FluentValue::String(s) => s, - FluentValue::Number(n) => n.as_string(), + FluentValue::Number(n) => n.as_string(scope.bundle), FluentValue::Custom(s) => scope.bundle.intls.stringify_value(s.as_ref()), FluentValue::Error => "".into(), FluentValue::None => "".into(), diff --git a/fluent-bundle/src/types/number.rs b/fluent-bundle/src/types/number.rs index b9c3b2de..7bfc99ed 100644 --- a/fluent-bundle/src/types/number.rs +++ b/fluent-bundle/src/types/number.rs @@ -3,9 +3,19 @@ use std::convert::TryInto; use std::default::Default; use std::str::FromStr; +use fixed_decimal::{DoublePrecision, FixedDecimal}; +use icu_decimal::options::{FixedDecimalFormatterOptions, GroupingStrategy}; +use icu_decimal::provider::DecimalSymbolsV1Marker; +use icu_decimal::{DecimalError, FixedDecimalFormatter}; +use icu_locid::{LanguageIdentifier as IcuLanguageIdentifier, ParserError}; +use icu_provider::prelude::*; +use intl_memoizer::Memoizable; use intl_pluralrules::operands::PluralOperands; +use unic_langid::LanguageIdentifier; use crate::args::FluentArgs; +use crate::bundle::{FluentBundle, IcuDataProvider}; +use crate::memoizer::MemoizerKind; use crate::types::FluentValue; #[derive(Debug, Default, Copy, Clone, Hash, PartialEq, Eq)] @@ -63,13 +73,27 @@ impl From<&str> for FluentNumberCurrencyDisplayStyle { } } -#[derive(Debug, Clone, Hash, PartialEq, Eq)] +#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] +pub enum FluentNumberUseGrouping { + Auto, + False, + Always, + Min2, +} + +impl Default for FluentNumberUseGrouping { + fn default() -> Self { + Self::Auto + } +} + +#[derive(Default, Debug, Clone, Hash, PartialEq, Eq)] pub struct FluentNumberOptions { pub r#type: FluentNumberType, pub style: FluentNumberStyle, pub currency: Option, pub currency_display: FluentNumberCurrencyDisplayStyle, - pub use_grouping: bool, + pub use_grouping: FluentNumberUseGrouping, pub minimum_integer_digits: Option, pub minimum_fraction_digits: Option, pub maximum_fraction_digits: Option, @@ -77,23 +101,6 @@ pub struct FluentNumberOptions { pub maximum_significant_digits: Option, } -impl Default for FluentNumberOptions { - fn default() -> Self { - Self { - r#type: Default::default(), - style: Default::default(), - currency: None, - currency_display: Default::default(), - use_grouping: true, - minimum_integer_digits: None, - minimum_fraction_digits: None, - maximum_fraction_digits: None, - minimum_significant_digits: None, - maximum_significant_digits: None, - } - } -} - impl FluentNumberOptions { pub fn merge(&mut self, opts: &FluentArgs) { for (key, value) in opts.iter() { @@ -111,7 +118,12 @@ impl FluentNumberOptions { self.currency_display = n.as_ref().into(); } ("useGrouping", FluentValue::String(n)) => { - self.use_grouping = n != "false"; + self.use_grouping = match n.as_ref() { + "false" => FluentNumberUseGrouping::False, + "always" => FluentNumberUseGrouping::Always, + "min2" => FluentNumberUseGrouping::Min2, + _ => FluentNumberUseGrouping::Auto, + } } ("minimumIntegerDigits", FluentValue::Number(n)) => { self.minimum_integer_digits = Some(n.into()); @@ -145,22 +157,46 @@ impl FluentNumber { Self { value, options } } - pub fn as_string(&self) -> Cow<'static, str> { - let mut val = self.value.to_string(); + pub fn as_string(&self, bundle: &FluentBundle) -> Cow<'static, str> { + let fixed_decimal = self.as_fixed_decimal(); + let options = FormatterOptions { + use_grouping: self.options.use_grouping, + }; + if let Some(data_provider) = &bundle.icu_data_provider { + let formatted = bundle + .intls + .with_try_get_threadsafe::( + (options,), + data_provider, + |formatter| formatter.0.format_to_string(&fixed_decimal), + ) + .unwrap(); + return formatted.into(); + } + + fixed_decimal.to_string().into() + } + + fn as_fixed_decimal(&self) -> FixedDecimal { + let precision = if let Some(maxsd) = self.options.maximum_significant_digits { + DoublePrecision::SignificantDigits(maxsd as u8) + } else { + DoublePrecision::Floating + }; + + let mut fixed_decimal = FixedDecimal::try_from_f64(self.value, precision).unwrap(); + if let Some(minfd) = self.options.minimum_fraction_digits { - if let Some(pos) = val.find('.') { - let frac_num = val.len() - pos - 1; - let missing = if frac_num > minfd { - 0 - } else { - minfd - frac_num - }; - val = format!("{}{}", val, "0".repeat(missing)); - } else { - val = format!("{}.{}", val, "0".repeat(minfd)); - } + fixed_decimal.pad_end(-(minfd as i16)); } - val.into() + if let Some(minid) = self.options.minimum_integer_digits { + fixed_decimal.pad_start(minid as i16); + } + fixed_decimal + } + + pub fn as_string_basic(&self) -> String { + self.as_fixed_decimal().to_string() } } @@ -250,8 +286,61 @@ from_num!(i8 i16 i32 i64 i128 isize); from_num!(u8 u16 u32 u64 u128 usize); from_num!(f32 f64); +pub type NumberFormatProvider = Box>; + +#[derive(Clone, Hash, PartialEq, Eq)] +struct FormatterOptions { + use_grouping: FluentNumberUseGrouping, +} + +struct NumberFormatter(FixedDecimalFormatter); + +#[derive(Debug)] +#[allow(dead_code)] +enum NumberFormatterError { + ParserError(ParserError), + DecimalError(DecimalError), +} + +impl Memoizable for NumberFormatter { + type Args = (FormatterOptions,); + type Error = NumberFormatterError; + type DataProvider = IcuDataProvider; + + fn construct( + lang: LanguageIdentifier, + args: Self::Args, + data_provider: &Self::DataProvider, + ) -> Result { + let locale = to_icu_lang_id(lang).map_err(NumberFormatterError::ParserError)?; + + let mut options: FixedDecimalFormatterOptions = Default::default(); + options.grouping_strategy = match args.0.use_grouping { + FluentNumberUseGrouping::Auto => GroupingStrategy::Auto, + FluentNumberUseGrouping::False => GroupingStrategy::Never, + FluentNumberUseGrouping::Always => GroupingStrategy::Always, + FluentNumberUseGrouping::Min2 => GroupingStrategy::Min2, + }; + + let inner = FixedDecimalFormatter::try_new_with_any_provider( + data_provider, + &locale.into(), + options, + ) + .map_err(NumberFormatterError::DecimalError)?; + Ok(NumberFormatter(inner)) + } +} + +fn to_icu_lang_id(lang: LanguageIdentifier) -> Result { + return IcuLanguageIdentifier::try_from_locale_bytes(lang.to_string().as_bytes()); +} + #[cfg(test)] mod tests { + use super::to_icu_lang_id; + use unic_langid::langid; + use crate::types::FluentValue; #[test] @@ -261,4 +350,16 @@ mod tests { let z: FluentValue = y.into(); assert_eq!(z, FluentValue::try_number("1")); } + + #[test] + fn lang_to_icu() { + assert_eq!( + to_icu_lang_id(langid!("en-US")).unwrap(), + icu_locid::langid!("en-US") + ); + assert_eq!( + to_icu_lang_id(langid!("pl")).unwrap(), + icu_locid::langid!("pl") + ); + } } diff --git a/fluent-bundle/src/types/plural.rs b/fluent-bundle/src/types/plural.rs index 1151fd6d..b5c597d9 100644 --- a/fluent-bundle/src/types/plural.rs +++ b/fluent-bundle/src/types/plural.rs @@ -8,7 +8,13 @@ pub struct PluralRules(pub IntlPluralRules); impl Memoizable for PluralRules { type Args = (PluralRuleType,); type Error = &'static str; - fn construct(lang: LanguageIdentifier, args: Self::Args) -> Result { + type DataProvider = (); + + fn construct( + lang: LanguageIdentifier, + args: Self::Args, + _: &Self::DataProvider, + ) -> Result { let default_lang: LanguageIdentifier = "en".parse().unwrap(); let pr_lang = negotiate_languages( &[lang], diff --git a/fluent-bundle/tests/types_test.rs b/fluent-bundle/tests/types_test.rs index 08d4d9be..070fc59a 100644 --- a/fluent-bundle/tests/types_test.rs +++ b/fluent-bundle/tests/types_test.rs @@ -1,6 +1,7 @@ use fluent_bundle::resolver::Scope; use fluent_bundle::types::{ FluentNumber, FluentNumberCurrencyDisplayStyle, FluentNumberOptions, FluentNumberStyle, + FluentNumberUseGrouping, }; use fluent_bundle::FluentArgs; use fluent_bundle::FluentBundle; @@ -120,21 +121,39 @@ fn fluent_number_style() { assert_eq!(fno.style, FluentNumberStyle::Currency); assert_eq!(fno.currency, Some("EUR".to_string())); assert_eq!(fno.currency_display, FluentNumberCurrencyDisplayStyle::Code); - assert!(!fno.use_grouping); + assert_eq!(fno.use_grouping, FluentNumberUseGrouping::False); let num = FluentNumber::new(0.2, FluentNumberOptions::default()); - assert_eq!(num.as_string(), "0.2"); + assert_eq!(num.as_string_basic(), "0.2"); - let opts = FluentNumberOptions { + let mut opts = FluentNumberOptions { minimum_fraction_digits: Some(3), ..Default::default() }; let num = FluentNumber::new(0.2, opts.clone()); - assert_eq!(num.as_string(), "0.200"); + assert_eq!(num.as_string_basic(), "0.200"); - let num = FluentNumber::new(2.0, opts); - assert_eq!(num.as_string(), "2.000"); + let num = FluentNumber::new(2.0, opts.clone()); + assert_eq!(num.as_string_basic(), "2.000"); + + opts.minimum_integer_digits = Some(3); + opts.minimum_fraction_digits = None; + + let num = FluentNumber::new(2.0, opts.clone()); + assert_eq!(num.as_string_basic(), "002"); + + let num = FluentNumber::new(0.2, opts.clone()); + assert_eq!(num.as_string_basic(), "000.2"); + + opts.minimum_integer_digits = None; + opts.maximum_significant_digits = Some(4); + + let num = FluentNumber::new(12345.0, opts.clone()); + assert_eq!(num.as_string_basic(), "12340"); + + let num = FluentNumber::new(1.2345, opts); + assert_eq!(num.as_string_basic(), "1.234"); } #[test] @@ -154,3 +173,24 @@ fn fluent_number_to_operands() { } ); } + +#[test] +fn fluent_number_grouping() { + let langid_ars = langid!("ccp"); + let mut bundle: FluentBundle = FluentBundle::new(vec![langid_ars]); + bundle.set_icu_data_provider(Box::new(fluent_bundle::FluentIcuDataProvider)); + + let mut number = FluentNumber::from(1234567890.1234567); + + number.options.use_grouping = FluentNumberUseGrouping::False; + let no_grouping = number.as_string(&bundle); + assert_eq!(no_grouping, "𑄷𑄸𑄹𑄺𑄻𑄼𑄽𑄾𑄿𑄶.𑄷𑄸𑄹𑄺𑄻𑄼𑄽"); + + number.options.use_grouping = FluentNumberUseGrouping::Min2; + let long = number.as_string(&bundle); + assert_eq!(long, "𑄷,𑄸𑄹,𑄺𑄻,𑄼𑄽,𑄾𑄿𑄶.𑄷𑄸𑄹𑄺𑄻𑄼𑄽"); + + number.value = -1234.0; + let short = number.as_string(&bundle); + assert_eq!(short, "-𑄷𑄸𑄹𑄺"); +} diff --git a/intl-memoizer/examples/numberformat.rs b/intl-memoizer/examples/numberformat.rs index 793c890c..72ff8cfb 100644 --- a/intl-memoizer/examples/numberformat.rs +++ b/intl-memoizer/examples/numberformat.rs @@ -28,7 +28,12 @@ impl NumberFormat { impl Memoizable for NumberFormat { type Args = (NumberFormatOptions,); type Error = (); - fn construct(lang: LanguageIdentifier, args: Self::Args) -> Result { + type DataProvider = (); + fn construct( + lang: LanguageIdentifier, + args: Self::Args, + _: &Self::DataProvider, + ) -> Result { Self::new(lang, args.0) } } @@ -45,7 +50,7 @@ fn main() { maximum_fraction_digits: 5, }; let result = lang_memoizer - .with_try_get::((options,), |nf| nf.format(2)) + .with_try_get::((options,), &(), |nf| nf.format(2)) .unwrap(); assert_eq!(&result, "en-US: 2, MFD: 3"); @@ -57,7 +62,7 @@ fn main() { maximum_fraction_digits: 5, }; let result = lang_memoizer - .with_try_get::((options,), |nf| nf.format(1)) + .with_try_get::((options,), &(), |nf| nf.format(1)) .unwrap(); assert_eq!(&result, "en-US: 1, MFD: 3"); } @@ -70,7 +75,7 @@ fn main() { maximum_fraction_digits: 5, }; let result = lang_memoizer - .with_try_get::((options,), |nf| nf.format(7)) + .with_try_get::((options,), &(), |nf| nf.format(7)) .unwrap(); assert_eq!(&result, "en-US: 7, MFD: 3"); diff --git a/intl-memoizer/examples/pluralrules.rs b/intl-memoizer/examples/pluralrules.rs index a37f8d1a..cca6e7dd 100644 --- a/intl-memoizer/examples/pluralrules.rs +++ b/intl-memoizer/examples/pluralrules.rs @@ -13,7 +13,12 @@ impl PluralRules { impl Memoizable for PluralRules { type Args = (PluralRuleType,); type Error = &'static str; - fn construct(lang: LanguageIdentifier, args: Self::Args) -> Result { + type DataProvider = (); + fn construct( + lang: LanguageIdentifier, + args: Self::Args, + _: &Self::DataProvider, + ) -> Result { Self::new(lang, args.0) } } @@ -24,7 +29,7 @@ fn main() { let lang: LanguageIdentifier = "en".parse().unwrap(); let lang_memoizer = memoizer.get_for_lang(lang); let result = lang_memoizer - .with_try_get::((PluralRuleType::CARDINAL,), |pr| pr.0.select(5)) + .with_try_get::((PluralRuleType::CARDINAL,), &(), |pr| pr.0.select(5)) .unwrap(); assert_eq!(result, Ok(PluralCategory::OTHER)); diff --git a/intl-memoizer/src/concurrent.rs b/intl-memoizer/src/concurrent.rs index 0809f733..e8f36248 100644 --- a/intl-memoizer/src/concurrent.rs +++ b/intl-memoizer/src/concurrent.rs @@ -22,7 +22,12 @@ impl IntlLangMemoizer { /// Lazily initialize and run a formatter. See /// [`intl_memoizer::IntlLangMemoizer::with_try_get`](crate::IntlLangMemoizer::with_try_get) /// for documentation. - pub fn with_try_get(&self, args: I::Args, cb: U) -> Result + pub fn with_try_get( + &self, + args: I::Args, + data_provider: &I::DataProvider, + cb: U, + ) -> Result where Self: Sized, I: Memoizable + Sync + Send + 'static, @@ -37,7 +42,7 @@ impl IntlLangMemoizer { let e = match cache.entry(args.clone()) { Entry::Occupied(entry) => entry.into_mut(), Entry::Vacant(entry) => { - let val = I::construct(self.lang.clone(), args)?; + let val = I::construct(self.lang.clone(), args, data_provider)?; entry.insert(val) } }; diff --git a/intl-memoizer/src/lib.rs b/intl-memoizer/src/lib.rs index d9986571..1a2ba21b 100644 --- a/intl-memoizer/src/lib.rs +++ b/intl-memoizer/src/lib.rs @@ -22,9 +22,16 @@ pub trait Memoizable { /// Type of any errors that can occur during the construction process. type Error; + /// Type of shared data provider + type DataProvider; + /// Construct a formatter. This maps the [`Self::Args`] type to the actual constructor /// for an intl formatter. - fn construct(lang: LanguageIdentifier, args: Self::Args) -> Result + fn construct( + lang: LanguageIdentifier, + args: Self::Args, + data_provider: &Self::DataProvider, + ) -> Result where Self: std::marker::Sized; } @@ -92,9 +99,12 @@ pub trait Memoizable { /// /// If the constructor is fallible, than errors can be described here. /// type Error = (); /// +/// /// For accessing shared state to construct +/// type DataProvider = (); +/// /// /// This function wires together the `Args` and `Error` type to construct /// /// the intl API. In our example, there is -/// fn construct(lang: LanguageIdentifier, args: Self::Args) -> Result { +/// fn construct(lang: LanguageIdentifier, args: Self::Args, data_provider: &Self::DataProvider) -> Result { /// // Keep track for example purposes that this was constructed. /// increment_constructs(); /// @@ -121,13 +131,13 @@ pub trait Memoizable { /// // more details. /// /// let result1 = memoizer -/// .with_try_get::(construct_args.clone(), |intl_example| { +/// .with_try_get::(construct_args.clone(), &(), |intl_example| { /// intl_example.format(message1) /// }); /// /// // The memoized instance of `ExampleFormatter` will be re-used. /// let result2 = memoizer -/// .with_try_get::(construct_args.clone(), |intl_example| { +/// .with_try_get::(construct_args.clone(), &(), |intl_example| { /// intl_example.format(message2) /// }); /// @@ -149,13 +159,13 @@ pub trait Memoizable { /// /// // Since the constructor args changed, `ExampleFormatter` will be re-constructed. /// let result1 = memoizer -/// .with_try_get::(construct_args.clone(), |intl_example| { +/// .with_try_get::(construct_args.clone(), &(), |intl_example| { /// intl_example.format(message1) /// }); /// /// // The memoized instance of `ExampleFormatter` will be re-used. /// let result2 = memoizer -/// .with_try_get::(construct_args.clone(), |intl_example| { +/// .with_try_get::(construct_args.clone(), &(), |intl_example| { /// intl_example.format(message2) /// }); /// @@ -205,7 +215,12 @@ impl IntlLangMemoizer { /// /// U - The callback function. Takes an instance of `I` as the first parameter and /// returns the R value. - pub fn with_try_get(&self, construct_args: I::Args, callback: U) -> Result + pub fn with_try_get( + &self, + construct_args: I::Args, + data_provider: &I::DataProvider, + callback: U, + ) -> Result where Self: Sized, I: Memoizable + 'static, @@ -222,7 +237,7 @@ impl IntlLangMemoizer { let e = match cache.entry(construct_args.clone()) { Entry::Occupied(entry) => entry.into_mut(), Entry::Vacant(entry) => { - let val = I::construct(self.lang.clone(), construct_args)?; + let val = I::construct(self.lang.clone(), construct_args, data_provider)?; entry.insert(val) } }; @@ -269,7 +284,8 @@ impl IntlLangMemoizer { /// # impl Memoizable for ExampleFormatter { /// # type Args = (String,); /// # type Error = (); -/// # fn construct(lang: LanguageIdentifier, args: Self::Args) -> Result { +/// # type DataProvider = (); +/// # fn construct(lang: LanguageIdentifier, args: Self::Args, data_provider: &Self::DataProvider) -> Result { /// # Ok(Self { /// # lang, /// # prefix: args.0, @@ -295,7 +311,7 @@ impl IntlLangMemoizer { /// // /// // See `IntlLangMemoizer` for more details on this step. /// let en_us_result = en_us_memoizer -/// .with_try_get::(construct_args.clone(), |intl_example| { +/// .with_try_get::(construct_args.clone(), &(), |intl_example| { /// intl_example.format(message) /// }); /// @@ -312,7 +328,7 @@ impl IntlLangMemoizer { /// let de_de_memoizer: Rc = memoizer.get_for_lang(de_de); /// /// let de_de_result = de_de_memoizer -/// .with_try_get::(construct_args.clone(), |intl_example| { +/// .with_try_get::(construct_args.clone(), &(), |intl_example| { /// intl_example.format(message) /// }); /// @@ -380,7 +396,12 @@ mod tests { impl Memoizable for PluralRules { type Args = (PluralRuleType,); type Error = &'static str; - fn construct(lang: LanguageIdentifier, args: Self::Args) -> Result { + type DataProvider = (); + fn construct( + lang: LanguageIdentifier, + args: Self::Args, + _: &Self::DataProvider, + ) -> Result { Self::new(lang, args.0) } } @@ -394,7 +415,9 @@ mod tests { let en_memoizer = memoizer.get_for_lang(lang.clone()); let result = en_memoizer - .with_try_get::((PluralRuleType::CARDINAL,), |cb| cb.0.select(5)) + .with_try_get::((PluralRuleType::CARDINAL,), &(), |cb| { + cb.0.select(5) + }) .unwrap(); assert_eq!(result, Ok(PluralCategory::OTHER)); } @@ -403,7 +426,9 @@ mod tests { let en_memoizer = memoizer.get_for_lang(lang); let result = en_memoizer - .with_try_get::((PluralRuleType::CARDINAL,), |cb| cb.0.select(5)) + .with_try_get::((PluralRuleType::CARDINAL,), &(), |cb| { + cb.0.select(5) + }) .unwrap(); assert_eq!(result, Ok(PluralCategory::OTHER)); } @@ -420,7 +445,7 @@ mod tests { let memoizer = Arc::clone(&memoizer); threads.push(thread::spawn(move || { memoizer - .with_try_get::((PluralRuleType::CARDINAL,), |cb| { + .with_try_get::((PluralRuleType::CARDINAL,), &(), |cb| { cb.0.select(5) }) .expect("Failed to get a PluralRules result.")