tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

locale_core.rs (8865B)


      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 #[diplomat::bridge]
      6 #[diplomat::abi_rename = "icu4x_{0}_mv1"]
      7 #[diplomat::attr(auto, namespace = "icu4x")]
      8 pub mod ffi {
      9    use alloc::boxed::Box;
     10 
     11    use crate::unstable::errors::ffi::LocaleParseError;
     12 
     13    use writeable::Writeable;
     14 
     15    #[diplomat::opaque]
     16    /// An ICU4X Locale, capable of representing strings like `"en-US"`.
     17    #[diplomat::rust_link(icu::locale::Locale, Struct)]
     18    #[diplomat::rust_link(icu::locale::DataLocale, Struct, hidden)]
     19    #[diplomat::rust_link(icu::locale::DataLocale::into_locale, FnInStruct, hidden)]
     20    pub struct Locale(pub icu_locale_core::Locale);
     21 
     22    impl Locale {
     23        /// Construct an [`Locale`] from an locale identifier.
     24        ///
     25        /// This will run the complete locale parsing algorithm. If code size and
     26        /// performance are critical and the locale is of a known shape (such as
     27        /// `aa-BB`) use `create_und`, `set_language`, `set_script`, and `set_region`.
     28        #[diplomat::rust_link(icu::locale::Locale::try_from_str, FnInStruct)]
     29        #[diplomat::rust_link(icu::locale::Locale::try_from_utf8, FnInStruct, hidden)]
     30        #[diplomat::rust_link(icu::locale::Locale::from_str, FnInStruct, hidden)]
     31        #[diplomat::rust_link(icu::locale::DataLocale::from_str, FnInStruct, hidden)]
     32        #[diplomat::rust_link(icu::locale::DataLocale::try_from_str, FnInStruct, hidden)]
     33        #[diplomat::rust_link(icu::locale::DataLocale::try_from_utf8, FnInStruct, hidden)]
     34        #[diplomat::attr(all(supports = fallible_constructors, supports = named_constructors), named_constructor)]
     35        #[diplomat::demo(default_constructor)]
     36        pub fn from_string(name: &DiplomatStr) -> Result<Box<Locale>, LocaleParseError> {
     37            Ok(Box::new(Locale(icu_locale_core::Locale::try_from_utf8(
     38                name,
     39            )?)))
     40        }
     41 
     42        /// Construct a unknown [`Locale`] "und".
     43        #[diplomat::rust_link(icu::locale::Locale::UNKNOWN, AssociatedConstantInStruct)]
     44        #[diplomat::rust_link(icu::locale::DataLocale::default, FnInStruct, hidden)]
     45        #[diplomat::rust_link(icu::locale::DataLocale::is_unknown, FnInStruct, hidden)]
     46        #[diplomat::attr(all(supports = fallible_constructors, supports = named_constructors), named_constructor)]
     47        pub fn unknown() -> Box<Locale> {
     48            Box::new(Locale(icu_locale_core::Locale::UNKNOWN))
     49        }
     50 
     51        /// Clones the [`Locale`].
     52        #[diplomat::rust_link(icu::locale::Locale, Struct)]
     53        pub fn clone(&self) -> Box<Locale> {
     54            Box::new(Locale(self.0.clone()))
     55        }
     56 
     57        /// Returns a string representation of the `LanguageIdentifier` part of
     58        /// [`Locale`].
     59        #[diplomat::rust_link(icu::locale::Locale::id, StructField)]
     60        #[diplomat::attr(auto, getter)]
     61        pub fn basename(&self, write: &mut diplomat_runtime::DiplomatWrite) {
     62            let _infallible = self.0.id.write_to(write);
     63        }
     64 
     65        /// Returns a string representation of the unicode extension.
     66        #[diplomat::rust_link(icu::locale::Locale::extensions, StructField)]
     67        pub fn get_unicode_extension(
     68            &self,
     69            s: &DiplomatStr,
     70            write: &mut diplomat_runtime::DiplomatWrite,
     71        ) -> Option<()> {
     72            icu_locale_core::extensions::unicode::Key::try_from_utf8(s)
     73                .ok()
     74                .and_then(|k| self.0.extensions.unicode.keywords.get(&k))
     75                .map(|v| {
     76                    let _infallible = v.write_to(write);
     77                })
     78        }
     79 
     80        /// Returns a string representation of [`Locale`] language.
     81        #[diplomat::rust_link(icu::locale::Locale::id, StructField)]
     82        #[diplomat::attr(auto, getter)]
     83        pub fn language(&self, write: &mut diplomat_runtime::DiplomatWrite) {
     84            let _infallible = self.0.id.language.write_to(write);
     85        }
     86 
     87        /// Set the language part of the [`Locale`].
     88        #[diplomat::rust_link(icu::locale::Locale::try_from_str, FnInStruct)]
     89        #[diplomat::rust_link(icu::locale::Locale::try_from_utf8, FnInStruct, hidden)]
     90        #[diplomat::attr(auto, setter = "language")]
     91        pub fn set_language(&mut self, s: &DiplomatStr) -> Result<(), LocaleParseError> {
     92            self.0.id.language = if s.is_empty() {
     93                icu_locale_core::subtags::Language::UNKNOWN
     94            } else {
     95                icu_locale_core::subtags::Language::try_from_utf8(s)?
     96            };
     97            Ok(())
     98        }
     99 
    100        /// Returns a string representation of [`Locale`] region.
    101        #[diplomat::rust_link(icu::locale::Locale::id, StructField)]
    102        #[diplomat::attr(auto, getter)]
    103        pub fn region(&self, write: &mut diplomat_runtime::DiplomatWrite) -> Option<()> {
    104            self.0.id.region.map(|region| {
    105                let _infallible = region.write_to(write);
    106            })
    107        }
    108 
    109        /// Set the region part of the [`Locale`].
    110        #[diplomat::rust_link(icu::locale::Locale::try_from_str, FnInStruct)]
    111        #[diplomat::rust_link(icu::locale::Locale::try_from_utf8, FnInStruct, hidden)]
    112        #[diplomat::attr(all(supports = accessors, not(dart)), setter = "region")]
    113        pub fn set_region(&mut self, s: &DiplomatStr) -> Result<(), LocaleParseError> {
    114            self.0.id.region = if s.is_empty() {
    115                None
    116            } else {
    117                Some(icu_locale_core::subtags::Region::try_from_utf8(s)?)
    118            };
    119            Ok(())
    120        }
    121 
    122        /// Returns a string representation of [`Locale`] script.
    123        #[diplomat::rust_link(icu::locale::Locale::id, StructField)]
    124        #[diplomat::attr(auto, getter)]
    125        pub fn script(&self, write: &mut diplomat_runtime::DiplomatWrite) -> Option<()> {
    126            self.0.id.script.map(|script| {
    127                let _infallible = script.write_to(write);
    128            })
    129        }
    130 
    131        /// Set the script part of the [`Locale`]. Pass an empty string to remove the script.
    132        #[diplomat::rust_link(icu::locale::Locale::try_from_str, FnInStruct)]
    133        #[diplomat::rust_link(icu::locale::Locale::try_from_utf8, FnInStruct, hidden)]
    134        #[diplomat::attr(all(supports = accessors, not(dart)), setter = "script")]
    135        pub fn set_script(&mut self, s: &DiplomatStr) -> Result<(), LocaleParseError> {
    136            self.0.id.script = if s.is_empty() {
    137                None
    138            } else {
    139                Some(icu_locale_core::subtags::Script::try_from_utf8(s)?)
    140            };
    141            Ok(())
    142        }
    143 
    144        /// Normalizes a locale string.
    145        #[diplomat::rust_link(icu::locale::Locale::normalize, FnInStruct)]
    146        #[diplomat::rust_link(icu::locale::Locale::normalize_utf8, FnInStruct, hidden)]
    147        pub fn normalize(
    148            s: &DiplomatStr,
    149            write: &mut DiplomatWrite,
    150        ) -> Result<(), LocaleParseError> {
    151            let _infallible = icu_locale_core::Locale::normalize_utf8(s)?.write_to(write);
    152            Ok(())
    153        }
    154        /// Returns a string representation of [`Locale`].
    155        #[diplomat::rust_link(icu::locale::Locale::write_to, FnInStruct)]
    156        #[diplomat::rust_link(icu::locale::Locale::to_string, FnInStruct, hidden)]
    157        #[diplomat::rust_link(icu::locale::DataLocale::to_string, FnInStruct, hidden)]
    158        #[diplomat::rust_link(icu::locale::DataLocale::write_to, FnInStruct, hidden)]
    159        #[diplomat::attr(auto, stringifier)]
    160        pub fn to_string(&self, write: &mut diplomat_runtime::DiplomatWrite) {
    161            let _infallible = self.0.write_to(write);
    162        }
    163 
    164        #[diplomat::rust_link(icu::locale::Locale::normalizing_eq, FnInStruct)]
    165        pub fn normalizing_eq(&self, other: &DiplomatStr) -> bool {
    166            if let Ok(other) = core::str::from_utf8(other) {
    167                self.0.normalizing_eq(other)
    168            } else {
    169                // invalid UTF8 won't be allowed in locales anyway
    170                false
    171            }
    172        }
    173 
    174        #[diplomat::rust_link(icu::locale::Locale::strict_cmp, FnInStruct)]
    175        pub fn compare_to_string(&self, other: &DiplomatStr) -> core::cmp::Ordering {
    176            self.0.strict_cmp(other)
    177        }
    178 
    179        #[diplomat::rust_link(icu::locale::Locale::total_cmp, FnInStruct)]
    180        #[diplomat::rust_link(icu::locale::DataLocale::strict_cmp, FnInStruct, hidden)]
    181        #[diplomat::rust_link(icu::locale::DataLocale::total_cmp, FnInStruct, hidden)]
    182        #[diplomat::attr(auto, comparison)]
    183        pub fn compare_to(&self, other: &Self) -> core::cmp::Ordering {
    184            self.0.total_cmp(&other.0)
    185        }
    186    }
    187 }
    188 
    189 impl ffi::Locale {
    190    pub fn to_datalocale(&self) -> icu_provider::DataLocale {
    191        (&self.0).into()
    192    }
    193 }