icu_locale_core/preferences/extensions/unicode/keywords/regional_subdivision.rs
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
5use crate::preferences::extensions::unicode::errors::PreferencesParseError;
6use crate::preferences::extensions::unicode::struct_keyword;
7use crate::{
8 extensions::unicode::{SubdivisionId, Value},
9 subtags::Subtag,
10};
11
12struct_keyword!(
13 /// A Unicode Subdivision Identifier defines a regional subdivision used for locales.
14 ///
15 /// The valid values are listed in [LDML](https://unicode.org/reports/tr35/#UnicodeSubdivisionIdentifier).
16 ///
17 /// # Examples
18 ///
19 /// ```
20 /// use icu::locale::locale;
21 /// use icu::locale::extensions::unicode::key;
22 /// use icu::locale::preferences::extensions::unicode::keywords::RegionalSubdivision;
23 /// use writeable::assert_writeable_eq;
24 ///
25 /// // Texan English
26 /// let locale = locale!("en-US-u-sd-ustx");
27 ///
28 /// let normal_region = locale.id.region.unwrap();
29 /// let sd_extension_value = locale.extensions.unicode.keywords.get(&key!("sd")).unwrap();
30 /// let regional_subdivision = RegionalSubdivision::try_from(sd_extension_value.clone()).unwrap();
31 ///
32 /// assert_writeable_eq!(normal_region, "US");
33 /// assert_writeable_eq!(regional_subdivision.region, "US");
34 /// assert_writeable_eq!(regional_subdivision.suffix, "tx");
35 /// ```
36 ///
37 /// The subdivision "true" is not supported; see [CLDR-19163](https://unicode-org.atlassian.net/browse/CLDR-19163):
38 ///
39 /// ```
40 /// use icu::locale::extensions::unicode::value;
41 /// use icu::locale::preferences::extensions::unicode::keywords::RegionalSubdivision;
42 /// use icu::locale::preferences::extensions::unicode::errors::PreferencesParseError;
43 /// use writeable::assert_writeable_eq;
44 ///
45 /// assert!(matches!(
46 /// RegionalSubdivision::try_from(value!("true")),
47 /// Err(PreferencesParseError::InvalidKeywordValue),
48 /// ));
49 /// ```
50 [Copy]
51 RegionalSubdivision,
52 "sd",
53 SubdivisionId,
54 |input: &Value| {
55 input
56 .as_single_subtag()
57 .and_then(|subtag| subtag.as_str().parse().ok().map(Self))
58 .ok_or(PreferencesParseError::InvalidKeywordValue)
59 },
60 |input: &RegionalSubdivision| {
61 Value::from_subtag(Some(input.0.into_subtag()))
62 }
63);
64
65#[cfg(test)]
66mod test {
67 use super::*;
68 use crate::extensions::unicode;
69 use crate::extensions::unicode::subdivision_suffix;
70 use crate::subtags::region;
71
72 #[test]
73 fn region_subdivision_test() {
74 let val = unicode::value!("uksct");
75 let rg: RegionalSubdivision = val.try_into().unwrap();
76 assert_eq!(rg.region, region!("UK"));
77 assert_eq!(rg.suffix, subdivision_suffix!("sct"));
78
79 for i in &["4aabel", "a4bel", "ukabcde"] {
80 let val = Value::try_from_str(i).unwrap();
81 let rg: Result<RegionalSubdivision, _> = val.try_into();
82 assert!(rg.is_err());
83 }
84 }
85}