/rust/registry/src/index.crates.io-6f17d22bba15001f/icu_provider-1.5.0/src/fallback.rs
Line | Count | Source (jump to first uncovered line) |
1 | | // This file is part of ICU4X. For terms of use, please see the file |
2 | | // called LICENSE at the top level of the ICU4X source tree |
3 | | // (online at: https://github.com/unicode-org/icu4x/blob/main/LICENSE ). |
4 | | |
5 | | //! Options to define fallback behaviour. |
6 | | //! |
7 | | //! These options are consumed by the `LocaleFallbacker` in the `icu_locid_transforms` crate |
8 | | //! (or the `icu::locid_transforms` module), but are defined here because they are used by `DataKey`. |
9 | | |
10 | | use icu_locid::extensions::unicode::Key; |
11 | | |
12 | | /// Hint for which subtag to prioritize during fallback. |
13 | | /// |
14 | | /// For example, `"en-US"` might fall back to either `"en"` or `"und-US"` depending |
15 | | /// on this enum. |
16 | | #[derive(Debug, PartialEq, Eq, Copy, Clone, PartialOrd, Ord)] |
17 | | #[non_exhaustive] |
18 | | pub enum LocaleFallbackPriority { |
19 | | /// Prioritize the language. This is the default behavior. |
20 | | /// |
21 | | /// For example, `"en-US"` should go to `"en"` and then `"und"`. |
22 | | Language, |
23 | | /// Prioritize the region. |
24 | | /// |
25 | | /// For example, `"en-US"` should go to `"und-US"` and then `"und"`. |
26 | | Region, |
27 | | /// Collation-specific fallback rules. Similar to language priority. |
28 | | /// |
29 | | /// For example, `"zh-Hant"` goes to `"zh"` before `"und"`. |
30 | | Collation, |
31 | | } |
32 | | |
33 | | impl LocaleFallbackPriority { |
34 | | /// Const-friendly version of [`Default::default`]. |
35 | 0 | pub const fn const_default() -> Self { |
36 | 0 | Self::Language |
37 | 0 | } |
38 | | } |
39 | | |
40 | | impl Default for LocaleFallbackPriority { |
41 | 0 | fn default() -> Self { |
42 | 0 | Self::const_default() |
43 | 0 | } |
44 | | } |
45 | | |
46 | | /// What additional data is required to load when performing fallback. |
47 | | #[derive(Debug, PartialEq, Eq, Copy, Clone, PartialOrd, Ord)] |
48 | | #[non_exhaustive] |
49 | | pub enum LocaleFallbackSupplement { |
50 | | /// Collation supplement |
51 | | Collation, |
52 | | } |
53 | | |
54 | | /// Configuration settings for a particular fallback operation. |
55 | | #[derive(Debug, Clone, PartialEq, Eq, Copy)] |
56 | | #[non_exhaustive] |
57 | | pub struct LocaleFallbackConfig { |
58 | | /// Strategy for choosing which subtags to drop during locale fallback. |
59 | | /// |
60 | | /// # Examples |
61 | | /// |
62 | | /// Retain the language and script subtags until the final step: |
63 | | /// |
64 | | /// ``` |
65 | | /// use icu::locid::locale; |
66 | | /// use icu::locid_transform::fallback::LocaleFallbackConfig; |
67 | | /// use icu::locid_transform::fallback::LocaleFallbackPriority; |
68 | | /// use icu::locid_transform::LocaleFallbacker; |
69 | | /// |
70 | | /// // Set up the fallback iterator. |
71 | | /// let fallbacker = LocaleFallbacker::new(); |
72 | | /// let mut config = LocaleFallbackConfig::default(); |
73 | | /// config.priority = LocaleFallbackPriority::Language; |
74 | | /// let mut fallback_iterator = fallbacker |
75 | | /// .for_config(config) |
76 | | /// .fallback_for(locale!("ca-ES-valencia").into()); |
77 | | /// |
78 | | /// // Run the algorithm and check the results. |
79 | | /// assert_eq!(fallback_iterator.get(), &locale!("ca-ES-valencia").into()); |
80 | | /// fallback_iterator.step(); |
81 | | /// assert_eq!(fallback_iterator.get(), &locale!("ca-ES").into()); |
82 | | /// fallback_iterator.step(); |
83 | | /// assert_eq!(fallback_iterator.get(), &locale!("ca-valencia").into()); |
84 | | /// fallback_iterator.step(); |
85 | | /// assert_eq!(fallback_iterator.get(), &locale!("ca").into()); |
86 | | /// fallback_iterator.step(); |
87 | | /// assert_eq!(fallback_iterator.get(), &locale!("und").into()); |
88 | | /// ``` |
89 | | /// |
90 | | /// Retain the region subtag until the final step: |
91 | | /// |
92 | | /// ``` |
93 | | /// use icu::locid::locale; |
94 | | /// use icu::locid_transform::fallback::LocaleFallbackConfig; |
95 | | /// use icu::locid_transform::fallback::LocaleFallbackPriority; |
96 | | /// use icu::locid_transform::LocaleFallbacker; |
97 | | /// |
98 | | /// // Set up the fallback iterator. |
99 | | /// let fallbacker = LocaleFallbacker::new(); |
100 | | /// let mut config = LocaleFallbackConfig::default(); |
101 | | /// config.priority = LocaleFallbackPriority::Region; |
102 | | /// let mut fallback_iterator = fallbacker |
103 | | /// .for_config(config) |
104 | | /// .fallback_for(locale!("ca-ES-valencia").into()); |
105 | | /// |
106 | | /// // Run the algorithm and check the results. |
107 | | /// assert_eq!(fallback_iterator.get(), &locale!("ca-ES-valencia").into()); |
108 | | /// fallback_iterator.step(); |
109 | | /// assert_eq!(fallback_iterator.get(), &locale!("ca-ES").into()); |
110 | | /// fallback_iterator.step(); |
111 | | /// assert_eq!(fallback_iterator.get(), &locale!("und-ES-valencia").into()); |
112 | | /// fallback_iterator.step(); |
113 | | /// assert_eq!(fallback_iterator.get(), &locale!("und-ES").into()); |
114 | | /// fallback_iterator.step(); |
115 | | /// assert_eq!(fallback_iterator.get(), &locale!("und").into()); |
116 | | /// ``` |
117 | | pub priority: LocaleFallbackPriority, |
118 | | /// An extension keyword to retain during locale fallback. |
119 | | /// |
120 | | /// # Examples |
121 | | /// |
122 | | /// ``` |
123 | | /// use icu::locid::locale; |
124 | | /// use icu::locid_transform::fallback::LocaleFallbackConfig; |
125 | | /// use icu::locid_transform::LocaleFallbacker; |
126 | | /// |
127 | | /// // Set up the fallback iterator. |
128 | | /// let fallbacker = LocaleFallbacker::new(); |
129 | | /// let mut config = LocaleFallbackConfig::default(); |
130 | | /// config.extension_key = Some(icu::locid::extensions::unicode::key!("nu")); |
131 | | /// let mut fallback_iterator = fallbacker |
132 | | /// .for_config(config) |
133 | | /// .fallback_for(locale!("ar-EG-u-nu-latn").into()); |
134 | | /// |
135 | | /// // Run the algorithm and check the results. |
136 | | /// assert_eq!(fallback_iterator.get(), &locale!("ar-EG-u-nu-latn").into()); |
137 | | /// fallback_iterator.step(); |
138 | | /// assert_eq!(fallback_iterator.get(), &locale!("ar-EG").into()); |
139 | | /// fallback_iterator.step(); |
140 | | /// assert_eq!(fallback_iterator.get(), &locale!("ar-u-nu-latn").into()); |
141 | | /// fallback_iterator.step(); |
142 | | /// assert_eq!(fallback_iterator.get(), &locale!("ar").into()); |
143 | | /// fallback_iterator.step(); |
144 | | /// assert_eq!(fallback_iterator.get(), &locale!("und").into()); |
145 | | /// ``` |
146 | | pub extension_key: Option<Key>, |
147 | | /// Fallback supplement data key to customize fallback rules. |
148 | | /// |
149 | | /// For example, most data keys for collation add additional parent locales, such as |
150 | | /// "yue" to "zh-Hant", and data used for the `"-u-co"` extension keyword fallback. |
151 | | /// |
152 | | /// Currently the only supported fallback supplement is `LocaleFallbackSupplement::Collation`, but more may be |
153 | | /// added in the future. |
154 | | /// |
155 | | /// # Examples |
156 | | /// |
157 | | /// ``` |
158 | | /// use icu::locid::locale; |
159 | | /// use icu::locid_transform::fallback::LocaleFallbackConfig; |
160 | | /// use icu::locid_transform::fallback::LocaleFallbackPriority; |
161 | | /// use icu::locid_transform::fallback::LocaleFallbackSupplement; |
162 | | /// use icu::locid_transform::LocaleFallbacker; |
163 | | /// |
164 | | /// // Set up the fallback iterator. |
165 | | /// let fallbacker = LocaleFallbacker::new(); |
166 | | /// let mut config = LocaleFallbackConfig::default(); |
167 | | /// config.priority = LocaleFallbackPriority::Collation; |
168 | | /// config.fallback_supplement = Some(LocaleFallbackSupplement::Collation); |
169 | | /// let mut fallback_iterator = fallbacker |
170 | | /// .for_config(config) |
171 | | /// .fallback_for(locale!("yue-HK").into()); |
172 | | /// |
173 | | /// // Run the algorithm and check the results. |
174 | | /// assert_eq!(fallback_iterator.get(), &locale!("yue-HK").into()); |
175 | | /// fallback_iterator.step(); |
176 | | /// assert_eq!(fallback_iterator.get(), &locale!("yue").into()); |
177 | | /// fallback_iterator.step(); |
178 | | /// assert_eq!(fallback_iterator.get(), &locale!("zh-Hant").into()); |
179 | | /// fallback_iterator.step(); |
180 | | /// assert_eq!(fallback_iterator.get(), &locale!("zh").into()); |
181 | | /// fallback_iterator.step(); |
182 | | /// assert_eq!(fallback_iterator.get(), &locale!("und").into()); |
183 | | /// ``` |
184 | | pub fallback_supplement: Option<LocaleFallbackSupplement>, |
185 | | } |
186 | | |
187 | | impl LocaleFallbackConfig { |
188 | | /// Const version of [`Default::default`]. |
189 | 0 | pub const fn const_default() -> Self { |
190 | 0 | Self { |
191 | 0 | priority: LocaleFallbackPriority::const_default(), |
192 | 0 | extension_key: None, |
193 | 0 | fallback_supplement: None, |
194 | 0 | } |
195 | 0 | } |
196 | | } |
197 | | |
198 | | impl Default for LocaleFallbackConfig { |
199 | 0 | fn default() -> Self { |
200 | 0 | Self::const_default() |
201 | 0 | } |
202 | | } |