tor-browser

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

collator.rs (11376B)


      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 use icu_collator::options::{CollatorOptions, ResolvedCollatorOptions};
      6 
      7 #[diplomat::bridge]
      8 #[diplomat::abi_rename = "icu4x_{0}_mv1"]
      9 #[diplomat::attr(auto, namespace = "icu4x")]
     10 pub mod ffi {
     11    use alloc::boxed::Box;
     12 
     13    #[cfg(feature = "buffer_provider")]
     14    use crate::unstable::provider::ffi::DataProvider;
     15    #[cfg(any(feature = "compiled_data", feature = "buffer_provider"))]
     16    use crate::unstable::{errors::ffi::DataError, locale_core::ffi::Locale};
     17    use diplomat_runtime::DiplomatOption;
     18 
     19    #[diplomat::opaque]
     20    #[diplomat::rust_link(icu::collator::Collator, Struct)]
     21    #[diplomat::rust_link(icu::collator::CollatorBorrowed, Struct, hidden)]
     22    pub struct Collator(pub icu_collator::Collator);
     23 
     24    #[diplomat::rust_link(icu::collator::options::CollatorOptions, Struct)]
     25    #[diplomat::rust_link(icu::collator::options::CollatorOptions::default, FnInStruct, hidden)]
     26    #[diplomat::attr(supports = non_exhaustive_structs, rename = "CollatorOptions")]
     27    pub struct CollatorOptionsV1 {
     28        pub strength: DiplomatOption<CollatorStrength>,
     29        pub alternate_handling: DiplomatOption<CollatorAlternateHandling>,
     30        pub max_variable: DiplomatOption<CollatorMaxVariable>,
     31        pub case_level: DiplomatOption<CollatorCaseLevel>,
     32    }
     33 
     34    // Note the flipped order of the words `Collator` and `Resolved`, because
     35    // in FFI `Collator` is part of the `Collator` prefix, but in Rust,
     36    // `ResolvedCollatorOptions` makes more sense as English.
     37    #[diplomat::rust_link(icu::collator::options::ResolvedCollatorOptions, Struct)]
     38    #[diplomat::out]
     39    #[diplomat::attr(supports = non_exhaustive_structs, rename = "CollatorResolvedOptions")]
     40    pub struct CollatorResolvedOptionsV1 {
     41        pub strength: CollatorStrength,
     42        pub alternate_handling: CollatorAlternateHandling,
     43        pub case_first: CollatorCaseFirst,
     44        pub max_variable: CollatorMaxVariable,
     45        pub case_level: CollatorCaseLevel,
     46        pub numeric: CollatorNumericOrdering,
     47    }
     48 
     49    #[diplomat::rust_link(icu::collator::options::Strength, Enum)]
     50    #[derive(Eq, PartialEq, Debug, PartialOrd, Ord)]
     51    #[diplomat::enum_convert(icu_collator::options::Strength, needs_wildcard)]
     52    pub enum CollatorStrength {
     53        Primary = 0,
     54        Secondary = 1,
     55        Tertiary = 2,
     56        Quaternary = 3,
     57        Identical = 4,
     58    }
     59 
     60    #[diplomat::rust_link(icu::collator::options::AlternateHandling, Enum)]
     61    #[derive(Eq, PartialEq, Debug, PartialOrd, Ord)]
     62    #[diplomat::enum_convert(icu_collator::options::AlternateHandling, needs_wildcard)]
     63    pub enum CollatorAlternateHandling {
     64        NonIgnorable = 0,
     65        Shifted = 1,
     66    }
     67 
     68    #[diplomat::rust_link(icu::collator::preferences::CollationCaseFirst, Enum)]
     69    #[derive(Eq, PartialEq, Debug, PartialOrd, Ord)]
     70    pub enum CollatorCaseFirst {
     71        Off = 0,
     72        Lower = 1,
     73        Upper = 2,
     74    }
     75 
     76    #[diplomat::rust_link(icu::collator::options::MaxVariable, Enum)]
     77    #[derive(Eq, PartialEq, Debug, PartialOrd, Ord)]
     78    #[diplomat::enum_convert(icu_collator::options::MaxVariable, needs_wildcard)]
     79    pub enum CollatorMaxVariable {
     80        Space = 0,
     81        Punctuation = 1,
     82        Symbol = 2,
     83        Currency = 3,
     84    }
     85 
     86    #[diplomat::rust_link(icu::collator::options::CaseLevel, Enum)]
     87    #[derive(Eq, PartialEq, Debug, PartialOrd, Ord)]
     88    #[diplomat::enum_convert(icu_collator::options::CaseLevel, needs_wildcard)]
     89    pub enum CollatorCaseLevel {
     90        Off = 0,
     91        On = 1,
     92    }
     93 
     94    #[diplomat::rust_link(icu::collator::preferences::CollationNumericOrdering, Enum)]
     95    #[derive(Eq, PartialEq, Debug, PartialOrd, Ord)]
     96    pub enum CollatorNumericOrdering {
     97        Off = 0,
     98        On = 1,
     99    }
    100 
    101    impl Collator {
    102        /// Construct a new Collator instance using compiled data.
    103        #[diplomat::rust_link(icu::collator::Collator::try_new, FnInStruct)]
    104        #[diplomat::rust_link(icu::collator::CollatorBorrowed::try_new, FnInStruct, hidden)]
    105        #[diplomat::rust_link(icu::collator::CollatorPreferences, Struct, hidden)]
    106        #[diplomat::rust_link(icu::collator::CollatorPreferences::extend, FnInStruct, hidden)]
    107        #[diplomat::attr(all(supports = fallible_constructors, supports = named_constructors), named_constructor = "with_provider")]
    108        #[diplomat::attr(supports = non_exhaustive_structs, rename = "create")]
    109        #[cfg(feature = "compiled_data")]
    110        pub fn create_v1(
    111            locale: &Locale,
    112            options: CollatorOptionsV1,
    113        ) -> Result<Box<Collator>, DataError> {
    114            Ok(Box::new(Collator(
    115                icu_collator::Collator::try_new((&locale.0).into(), options.into())?
    116                    .static_to_owned(),
    117            )))
    118        }
    119 
    120        /// Construct a new Collator instance using a particular data source.
    121        #[diplomat::rust_link(icu::collator::Collator::try_new, FnInStruct)]
    122        #[diplomat::rust_link(icu::collator::CollatorBorrowed::try_new, FnInStruct, hidden)]
    123        #[diplomat::rust_link(icu::collator::CollatorPreferences, Struct, hidden)]
    124        #[diplomat::attr(supports = fallible_constructors, constructor)]
    125        #[diplomat::attr(supports = non_exhaustive_structs, rename = "create_with_provider")]
    126        #[cfg(feature = "buffer_provider")]
    127        pub fn create_v1_with_provider(
    128            provider: &DataProvider,
    129            locale: &Locale,
    130            options: CollatorOptionsV1,
    131        ) -> Result<Box<Collator>, DataError> {
    132            let options = options.into();
    133            Ok(Box::new(Collator(
    134                icu_collator::Collator::try_new_with_buffer_provider(
    135                    provider.get()?,
    136                    (&locale.0).into(),
    137                    options,
    138                )?,
    139            )))
    140        }
    141        /// Compare two strings.
    142        ///
    143        /// Ill-formed input is treated as if errors had been replaced with REPLACEMENT CHARACTERs according
    144        /// to the WHATWG Encoding Standard.
    145        #[diplomat::rust_link(icu::collator::CollatorBorrowed::compare_utf8, FnInStruct)]
    146        #[diplomat::rust_link(icu::collator::CollatorBorrowed::compare, FnInStruct, hidden)]
    147        #[diplomat::attr(not(supports = utf8_strings), disable)]
    148        #[diplomat::attr(supports = utf8_strings, rename = "compare")]
    149        pub fn compare_utf8(&self, left: &DiplomatStr, right: &DiplomatStr) -> core::cmp::Ordering {
    150            self.0.as_borrowed().compare_utf8(left, right)
    151        }
    152 
    153        /// Compare two strings.
    154        ///
    155        /// Ill-formed input is treated as if errors had been replaced with REPLACEMENT CHARACTERs according
    156        /// to the WHATWG Encoding Standard.
    157        #[diplomat::rust_link(icu::collator::CollatorBorrowed::compare_utf16, FnInStruct)]
    158        #[diplomat::attr(not(supports = utf8_strings), rename = "compare")]
    159        #[diplomat::attr(supports = utf8_strings, rename = "compare16")]
    160        pub fn compare_utf16(
    161            &self,
    162            left: &DiplomatStr16,
    163            right: &DiplomatStr16,
    164        ) -> core::cmp::Ordering {
    165            self.0.as_borrowed().compare_utf16(left, right)
    166        }
    167 
    168        /// The resolved options showing how the default options, the requested options,
    169        /// and the options from locale data were combined. None of the struct fields
    170        /// will have `Auto` as the value.
    171        #[diplomat::rust_link(icu::collator::CollatorBorrowed::resolved_options, FnInStruct)]
    172        #[diplomat::attr(auto, getter)]
    173        #[diplomat::attr(supports = non_exhaustive_structs, rename = "resolved_options")]
    174        pub fn resolved_options_v1(&self) -> CollatorResolvedOptionsV1 {
    175            self.0.as_borrowed().resolved_options().into()
    176        }
    177    }
    178 }
    179 
    180 impl From<ffi::CollatorOptionsV1> for CollatorOptions {
    181    fn from(options: ffi::CollatorOptionsV1) -> CollatorOptions {
    182        let mut result = CollatorOptions::default();
    183        result.strength = options.strength.into_converted_option();
    184        result.alternate_handling = options.alternate_handling.into_converted_option();
    185        result.max_variable = options.max_variable.into_converted_option();
    186        result.case_level = options.case_level.into_converted_option();
    187 
    188        result
    189    }
    190 }
    191 
    192 impl From<ResolvedCollatorOptions> for ffi::CollatorResolvedOptionsV1 {
    193    fn from(options: ResolvedCollatorOptions) -> ffi::CollatorResolvedOptionsV1 {
    194        Self {
    195            strength: options.strength.into(),
    196            alternate_handling: options.alternate_handling.into(),
    197            case_first: options.case_first.into(),
    198            max_variable: options.max_variable.into(),
    199            case_level: options.case_level.into(),
    200            numeric: options.numeric.into(),
    201        }
    202    }
    203 }
    204 
    205 impl From<icu_collator::preferences::CollationCaseFirst> for ffi::CollatorCaseFirst {
    206    fn from(other: icu_collator::preferences::CollationCaseFirst) -> Self {
    207        match other {
    208            icu_collator::preferences::CollationCaseFirst::Upper => ffi::CollatorCaseFirst::Upper,
    209            icu_collator::preferences::CollationCaseFirst::Lower => ffi::CollatorCaseFirst::Lower,
    210            icu_collator::preferences::CollationCaseFirst::False => ffi::CollatorCaseFirst::Off,
    211            _ => {
    212                debug_assert!(
    213                    false,
    214                    "unknown variant for icu_collator::preferences::CollationCaseFirst"
    215                );
    216                ffi::CollatorCaseFirst::Off
    217            }
    218        }
    219    }
    220 }
    221 impl From<ffi::CollatorCaseFirst> for icu_collator::preferences::CollationCaseFirst {
    222    fn from(this: ffi::CollatorCaseFirst) -> Self {
    223        match this {
    224            ffi::CollatorCaseFirst::Off => icu_collator::preferences::CollationCaseFirst::False,
    225            ffi::CollatorCaseFirst::Lower => icu_collator::preferences::CollationCaseFirst::Lower,
    226            ffi::CollatorCaseFirst::Upper => icu_collator::preferences::CollationCaseFirst::Upper,
    227        }
    228    }
    229 }
    230 
    231 impl From<icu_collator::preferences::CollationNumericOrdering> for ffi::CollatorNumericOrdering {
    232    fn from(other: icu_collator::preferences::CollationNumericOrdering) -> Self {
    233        match other {
    234            icu_collator::preferences::CollationNumericOrdering::True => {
    235                ffi::CollatorNumericOrdering::On
    236            }
    237            icu_collator::preferences::CollationNumericOrdering::False => {
    238                ffi::CollatorNumericOrdering::Off
    239            }
    240            _ => {
    241                debug_assert!(
    242                    false,
    243                    "unknown variant for icu_collator::preferences::CollationNumericOrdering"
    244                );
    245                ffi::CollatorNumericOrdering::Off
    246            }
    247        }
    248    }
    249 }
    250 impl From<ffi::CollatorNumericOrdering> for icu_collator::preferences::CollationNumericOrdering {
    251    fn from(this: ffi::CollatorNumericOrdering) -> Self {
    252        match this {
    253            ffi::CollatorNumericOrdering::Off => {
    254                icu_collator::preferences::CollationNumericOrdering::False
    255            }
    256            ffi::CollatorNumericOrdering::On => {
    257                icu_collator::preferences::CollationNumericOrdering::True
    258            }
    259        }
    260    }
    261 }