// 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::{provider::*, LocaleTransformError}; use core::mem; use icu_locid::subtags::{Language, Region, Script}; use icu_locid::LanguageIdentifier; use icu_provider::prelude::*; use crate::TransformResult; /// Implements the *Add Likely Subtags* and *Remove Likely Subtags* /// algorithms as defined in *[UTS #35: Likely Subtags]*. /// /// # Examples /// /// Add likely subtags: /// /// ``` /// use icu_locid::locale; /// use icu_locid_transform::{LocaleExpander, TransformResult}; /// /// let lc = LocaleExpander::new(); /// /// let mut locale = locale!("zh-CN"); /// assert_eq!(lc.maximize(&mut locale), TransformResult::Modified); /// assert_eq!(locale, locale!("zh-Hans-CN")); /// /// let mut locale = locale!("zh-Hant-TW"); /// assert_eq!(lc.maximize(&mut locale), TransformResult::Unmodified); /// assert_eq!(locale, locale!("zh-Hant-TW")); /// ``` /// /// Remove likely subtags: /// /// ``` /// use icu_locid::locale; /// use icu_locid_transform::{LocaleExpander, TransformResult}; /// /// let lc = LocaleExpander::new(); /// /// let mut locale = locale!("zh-Hans-CN"); /// assert_eq!(lc.minimize(&mut locale), TransformResult::Modified); /// assert_eq!(locale, locale!("zh")); /// /// let mut locale = locale!("zh"); /// assert_eq!(lc.minimize(&mut locale), TransformResult::Unmodified); /// assert_eq!(locale, locale!("zh")); /// ``` /// /// Normally, only CLDR locales with Basic or higher coverage are included. To include more /// locales for maximization, use [`try_new_extended`](Self::try_new_extended_unstable): /// /// ``` /// use icu_locid::locale; /// use icu_locid_transform::{LocaleExpander, TransformResult}; /// /// let lc = LocaleExpander::new_extended(); /// /// let mut locale = locale!("atj"); /// assert_eq!(lc.maximize(&mut locale), TransformResult::Modified); /// assert_eq!(locale, locale!("atj-Latn-CA")); /// ``` /// /// [UTS #35: Likely Subtags]: https://www.unicode.org/reports/tr35/#Likely_Subtags #[derive(Debug, Clone)] pub struct LocaleExpander { likely_subtags_l: DataPayload, likely_subtags_sr: DataPayload, likely_subtags_ext: Option>, } struct LocaleExpanderBorrowed<'a> { likely_subtags_l: &'a LikelySubtagsForLanguageV1<'a>, likely_subtags_sr: &'a LikelySubtagsForScriptRegionV1<'a>, likely_subtags_ext: Option<&'a LikelySubtagsExtendedV1<'a>>, } impl LocaleExpanderBorrowed<'_> { fn get_l(&self, l: Language) -> Option<(Script, Region)> { let key = &l.into_tinystr().to_unvalidated(); self.likely_subtags_l.language.get_copied(key).or_else(|| { self.likely_subtags_ext .and_then(|ext| ext.language.get_copied(key)) }) } fn get_ls(&self, l: Language, s: Script) -> Option { let key = &( l.into_tinystr().to_unvalidated(), s.into_tinystr().to_unvalidated(), ); self.likely_subtags_l .language_script .get_copied(key) .or_else(|| { self.likely_subtags_ext .and_then(|ext| ext.language_script.get_copied(key)) }) } fn get_lr(&self, l: Language, r: Region) -> Option