icu_provider_source/decimal/
mod.rs
1use std::collections::HashSet;
6
7use crate::cldr_serde;
8use crate::SourceDataProvider;
9use icu_locale_core::locale;
10use icu_provider::prelude::*;
11
12#[cfg(feature = "experimental")]
13mod compact;
14#[cfg(feature = "experimental")]
15mod compact_decimal_pattern;
16pub(crate) mod decimal_pattern;
17mod symbols;
18
19mod digits;
20
21impl SourceDataProvider {
22 fn get_digits_for_numbering_system(&self, nsname: &str) -> Result<[char; 10], DataError> {
24 let resource: &cldr_serde::numbering_systems::Resource = self
25 .cldr()?
26 .core()
27 .read_and_parse("supplemental/numberingSystems.json")?;
28
29 fn digits_str_to_chars(digits_str: &str) -> Option<[char; 10]> {
30 let mut chars = digits_str.chars();
31 Some([
32 chars.next()?,
33 chars.next()?,
34 chars.next()?,
35 chars.next()?,
36 chars.next()?,
37 chars.next()?,
38 chars.next()?,
39 chars.next()?,
40 chars.next()?,
41 chars.next()?,
42 ])
43 }
44
45 match resource.supplemental.numbering_systems.get(nsname) {
46 Some(ns) => ns.digits.as_deref().and_then(digits_str_to_chars),
47 None => None,
48 }
49 .ok_or_else(|| {
50 DataError::custom("Could not process numbering system").with_display_context(nsname)
51 })
52 }
53
54 fn get_supported_numsys_for_langid(
56 &self,
57 locale: &DataLocale,
58 exclude_default: bool,
59 ) -> Result<Vec<Box<DataMarkerAttributes>>, DataError> {
60 let resource: &cldr_serde::numbers::Resource = self
61 .cldr()?
62 .numbers()
63 .read_and_parse(locale, "numbers.json")?;
64
65 let numbers = &resource.main.value.numbers;
66
67 Ok(numbers
68 .numsys_data
69 .symbols
70 .keys()
71 .filter(|nsname| !exclude_default || **nsname != numbers.default_numbering_system)
72 .filter_map(|nsname| Some(DataMarkerAttributes::try_from_str(nsname).ok()?.to_owned()))
73 .collect())
74 }
75
76 fn iter_ids_for_numbers_with_locales(
79 &self,
80 ) -> Result<HashSet<DataIdentifierCow<'static>>, DataError> {
81 Ok(self
82 .cldr()?
83 .numbers()
84 .list_locales()?
85 .flat_map(|locale| {
86 let last = locale;
87 self.get_supported_numsys_for_langid(&locale, true)
88 .expect("All languages from list_locales should be present")
89 .into_iter()
90 .map(move |nsname| {
91 DataIdentifierBorrowed::for_marker_attributes_and_locale(
92 DataMarkerAttributes::try_from_str(&nsname).unwrap(),
93 &locale,
94 )
95 .into_owned()
96 })
97 .chain([DataIdentifierCow::from_locale(last)])
98 })
99 .collect())
100 }
101
102 fn iter_ids_for_used_numbers(&self) -> Result<HashSet<DataIdentifierCow<'static>>, DataError> {
104 Ok(self
105 .cldr()?
106 .numbers()
107 .list_locales()?
108 .flat_map(|locale| {
109 self.get_supported_numsys_for_langid(&locale, false)
110 .expect("All languages from list_locales should be present")
111 .into_iter()
112 .map(move |nsname| {
113 DataIdentifierBorrowed::for_marker_attributes_and_locale(
114 DataMarkerAttributes::try_from_str(&nsname).unwrap(),
115 &locale!("und").into(),
116 )
117 .into_owned()
118 })
119 })
120 .collect())
121 }
122
123 #[allow(unused)] fn iter_all_number_ids(&self) -> Result<HashSet<DataIdentifierCow<'static>>, DataError> {
126 use cldr_serde::numbering_systems::NumberingSystemType;
127 let resource: &cldr_serde::numbering_systems::Resource = self
128 .cldr()?
129 .core()
130 .read_and_parse("supplemental/numberingSystems.json")?;
131
132 Ok(resource
133 .supplemental
134 .numbering_systems
135 .iter()
136 .filter(|(_nsname, data)| data.nstype == NumberingSystemType::Numeric)
137 .map(|(nsname, _data)| {
138 DataIdentifierBorrowed::for_marker_attributes_and_locale(
139 DataMarkerAttributes::try_from_str(nsname).unwrap(),
140 &locale!("und").into(),
141 )
142 .into_owned()
143 })
144 .collect())
145 }
146}