icu_provider_source/currency/
extended.rs
1use crate::cldr_serde;
6use crate::SourceDataProvider;
7use icu::experimental::dimension::provider::extended_currency::*;
8use icu::plurals::PluralElements;
9use icu_provider::prelude::*;
10use std::collections::HashSet;
11
12impl DataProvider<CurrencyExtendedDataV1> for crate::SourceDataProvider {
13 fn load(&self, req: DataRequest) -> Result<DataResponse<CurrencyExtendedDataV1>, DataError> {
14 self.check_req::<CurrencyExtendedDataV1>(req)?;
15
16 let currencies_resource: &cldr_serde::currencies::data::Resource =
17 self.cldr()?
18 .numbers()
19 .read_and_parse(req.id.locale, "currencies.json")?;
20
21 let currency = currencies_resource
22 .main
23 .value
24 .numbers
25 .currencies
26 .get(req.id.marker_attributes.as_str())
27 .ok_or(DataError::custom("No currency associated with the aux key"))?;
28
29 Ok(DataResponse {
30 metadata: Default::default(),
31 payload: DataPayload::from_owned(CurrencyExtendedData {
32 display_names: PluralElements::new(
33 currency
34 .other
35 .as_deref()
36 .ok_or_else(|| DataErrorKind::IdentifierNotFound.into_error())?,
37 )
38 .with_zero_value(currency.zero.as_deref())
39 .with_one_value(currency.one.as_deref())
40 .with_two_value(currency.two.as_deref())
41 .with_few_value(currency.few.as_deref())
42 .with_many_value(currency.many.as_deref())
43 .with_explicit_one_value(currency.explicit_one.as_deref())
44 .with_explicit_zero_value(currency.explicit_zero.as_deref())
45 .into(),
46 }),
47 })
48 }
49}
50
51impl crate::IterableDataProviderCached<CurrencyExtendedDataV1> for SourceDataProvider {
52 fn iter_ids_cached(&self) -> Result<HashSet<DataIdentifierCow<'static>>, DataError> {
53 let mut result = HashSet::new();
54 let numbers = self.cldr()?.numbers();
55 let locales = numbers.list_locales()?;
56 for locale in locales {
57 let currencies_resource: &cldr_serde::currencies::data::Resource = self
58 .cldr()?
59 .numbers()
60 .read_and_parse(&locale, "currencies.json")?;
61
62 let currencies = ¤cies_resource.main.value.numbers.currencies;
63 for (currency, displaynames) in currencies {
64 if displaynames.other.is_none() {
72 continue;
73 }
74 if let Ok(attributes) = DataMarkerAttributes::try_from_string(currency.clone()) {
75 result.insert(DataIdentifierCow::from_owned(attributes, locale));
76 }
77 }
78 }
79
80 Ok(result)
81 }
82}
83
84#[test]
85fn test_basic() {
86 use icu::locale::langid;
87 use icu::plurals::PluralRules;
88 let provider = SourceDataProvider::new_testing();
89 let en: DataPayload<CurrencyExtendedDataV1> = provider
90 .load(DataRequest {
91 id: DataIdentifierBorrowed::for_marker_attributes_and_locale(
92 DataMarkerAttributes::from_str_or_panic("USD"),
93 &langid!("en").into(),
94 ),
95 ..Default::default()
96 })
97 .unwrap()
98 .payload;
99 let en_rules = PluralRules::try_new_cardinal_unstable(&provider, langid!("en").into()).unwrap();
100 assert_eq!(en.get().display_names.get(1.into(), &en_rules), "US dollar");
101 assert_eq!(
102 en.get().display_names.get(10.into(), &en_rules),
103 "US dollars"
104 );
105
106 let fr: DataPayload<CurrencyExtendedDataV1> = provider
107 .load(DataRequest {
108 id: DataIdentifierBorrowed::for_marker_attributes_and_locale(
109 DataMarkerAttributes::from_str_or_panic("USD"),
110 &langid!("fr").into(),
111 ),
112 ..Default::default()
113 })
114 .unwrap()
115 .payload;
116 let fr_rules = PluralRules::try_new_cardinal_unstable(&provider, langid!("fr").into()).unwrap();
117
118 assert_eq!(
119 fr.get().display_names.get(0.into(), &fr_rules),
120 "dollar des États-Unis"
121 );
122 assert_eq!(
123 fr.get().display_names.get(1.into(), &fr_rules),
124 "dollar des États-Unis"
125 );
126 assert_eq!(
127 fr.get().display_names.get(10.into(), &fr_rules),
128 "dollars des États-Unis"
129 );
130}