Skip to main content

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}