// This file is part of ICU4X. For terms of use, please see the file // called LICENSE at the top level of the ICU4X source tree // (online at: https://github.com/unicode-org/icu4x/blob/main/LICENSE ). use crate::ordering::SubtagOrderingResult; use crate::parser::{ get_subtag_iterator, parse_locale, parse_locale_with_single_variant_single_keyword_unicode_keyword_extension, ParserError, ParserMode, }; use crate::{extensions, subtags, LanguageIdentifier}; use alloc::string::String; use alloc::string::ToString; use core::cmp::Ordering; use core::str::FromStr; use tinystr::TinyAsciiStr; /// A core struct representing a [`Unicode Locale Identifier`]. /// /// A locale is made of two parts: /// * Unicode Language Identifier /// * A set of Unicode Extensions /// /// [`Locale`] exposes all of the same fields and methods as [`LanguageIdentifier`], and /// on top of that is able to parse, manipulate and serialize unicode extension fields. /// /// /// # Examples /// /// ``` /// use icu::locid::extensions::unicode::{Key, Value}; /// use icu::locid::{subtags::*, Locale}; /// /// let loc: Locale = "en-US-u-ca-buddhist".parse().expect("Failed to parse."); /// /// assert_eq!(loc.id.language, "en".parse::().unwrap()); /// assert_eq!(loc.id.script, None); /// assert_eq!(loc.id.region, "US".parse::().ok()); /// assert_eq!(loc.id.variants.len(), 0); /// assert_eq!(loc.to_string(), "en-US-u-ca-buddhist"); /// /// let key: Key = "ca".parse().expect("Parsing key failed."); /// let value: Value = "buddhist".parse().expect("Parsing value failed."); /// assert_eq!(loc.extensions.unicode.keywords.get(&key), Some(&value)); /// ``` /// /// # Parsing /// /// Unicode recognizes three levels of standard conformance for a locale: /// /// * *well-formed* - syntactically correct /// * *valid* - well-formed and only uses registered language subtags, extensions, keywords, types... /// * *canonical* - valid and no deprecated codes or structure. /// /// At the moment parsing normalizes a well-formed locale identifier converting /// `_` separators to `-` and adjusting casing to conform to the Unicode standard. /// /// Any bogus subtags will cause the parsing to fail with an error. /// No subtag validation or canonicalization is performed. /// /// # Examples /// /// ``` /// use icu::locid::{subtags::*, Locale}; /// /// let loc: Locale = "eN_latn_Us-Valencia_u-hC-H12" /// .parse() /// .expect("Failed to parse."); /// /// assert_eq!(loc.id.language, "en".parse::().unwrap()); /// assert_eq!(loc.id.script, "Latn".parse::