tor-browser

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

casemap.rs (19187B)


      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_casemap::options::TitlecaseOptions;
      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(any(feature = "compiled_data", feature = "buffer_provider"))]
     14    use crate::unstable::errors::ffi::DataError;
     15    use crate::unstable::locale_core::ffi::Locale;
     16    #[cfg(feature = "buffer_provider")]
     17    use crate::unstable::provider::ffi::DataProvider;
     18    use diplomat_runtime::DiplomatOption;
     19 
     20    use writeable::Writeable;
     21 
     22    #[diplomat::enum_convert(icu_casemap::options::LeadingAdjustment, needs_wildcard)]
     23    #[diplomat::rust_link(icu::casemap::options::LeadingAdjustment, Enum)]
     24    pub enum LeadingAdjustment {
     25        Auto,
     26        None,
     27        ToCased,
     28    }
     29 
     30    #[diplomat::enum_convert(icu_casemap::options::TrailingCase, needs_wildcard)]
     31    #[diplomat::rust_link(icu::casemap::options::TrailingCase, Enum)]
     32    pub enum TrailingCase {
     33        Lower,
     34        Unchanged,
     35    }
     36 
     37    #[diplomat::rust_link(icu::casemap::options::TitlecaseOptions, Struct)]
     38    #[diplomat::attr(supports = non_exhaustive_structs, rename = "TitlecaseOptions")]
     39    pub struct TitlecaseOptionsV1 {
     40        pub leading_adjustment: DiplomatOption<LeadingAdjustment>,
     41        pub trailing_case: DiplomatOption<TrailingCase>,
     42    }
     43 
     44    impl TitlecaseOptionsV1 {
     45        #[diplomat::rust_link(icu::casemap::options::TitlecaseOptions::default, FnInStruct)]
     46        #[diplomat::attr(auto, constructor)]
     47        #[diplomat::attr(any(cpp, js), rename = "default_options")]
     48        pub fn default() -> TitlecaseOptionsV1 {
     49            Self {
     50                leading_adjustment: None.into(),
     51                trailing_case: None.into(),
     52            }
     53        }
     54    }
     55 
     56    #[diplomat::opaque]
     57    #[diplomat::rust_link(icu::casemap::CaseMapper, Struct)]
     58    #[diplomat::rust_link(icu::casemap::CaseMapperBorrowed, Struct, hidden)]
     59    pub struct CaseMapper(pub icu_casemap::CaseMapper);
     60 
     61    impl CaseMapper {
     62        /// Construct a new CaseMapper instance using compiled data.
     63        #[diplomat::rust_link(icu::casemap::CaseMapper::new, FnInStruct)]
     64        #[diplomat::rust_link(icu::casemap::CaseMapperBorrowed::new, FnInStruct, hidden)]
     65        #[diplomat::attr(auto, constructor)]
     66        #[cfg(feature = "compiled_data")]
     67        pub fn create() -> Box<CaseMapper> {
     68            Box::new(CaseMapper(icu_casemap::CaseMapper::new().static_to_owned()))
     69        }
     70 
     71        /// Construct a new CaseMapper instance using a particular data source.
     72        #[diplomat::rust_link(icu::casemap::CaseMapper::new, FnInStruct)]
     73        #[diplomat::attr(all(supports = fallible_constructors, supports = named_constructors), named_constructor = "with_provider")]
     74        #[cfg(feature = "buffer_provider")]
     75        pub fn create_with_provider(provider: &DataProvider) -> Result<Box<CaseMapper>, DataError> {
     76            Ok(Box::new(CaseMapper(
     77                icu_casemap::CaseMapper::try_new_with_buffer_provider(provider.get()?)?,
     78            )))
     79        }
     80        /// Returns the full lowercase mapping of the given string
     81        #[diplomat::rust_link(icu::casemap::CaseMapperBorrowed::lowercase, FnInStruct)]
     82        #[diplomat::rust_link(
     83            icu::casemap::CaseMapperBorrowed::lowercase_to_string,
     84            FnInStruct,
     85            hidden
     86        )]
     87        pub fn lowercase(&self, s: &str, locale: &Locale, write: &mut DiplomatWrite) {
     88            let _infallible = self
     89                .0
     90                .as_borrowed()
     91                .lowercase(s, &locale.0.id)
     92                .write_to(write);
     93        }
     94 
     95        /// Returns the full uppercase mapping of the given string
     96        #[diplomat::rust_link(icu::casemap::CaseMapperBorrowed::uppercase, FnInStruct)]
     97        #[diplomat::rust_link(
     98            icu::casemap::CaseMapperBorrowed::uppercase_to_string,
     99            FnInStruct,
    100            hidden
    101        )]
    102        pub fn uppercase(&self, s: &str, locale: &Locale, write: &mut DiplomatWrite) {
    103            let _infallible = self
    104                .0
    105                .as_borrowed()
    106                .uppercase(s, &locale.0.id)
    107                .write_to(write);
    108        }
    109 
    110        /// Returns the full lowercase mapping of the given string, using compiled data (avoids having to allocate a CaseMapper object)
    111        #[diplomat::rust_link(icu::casemap::CaseMapperBorrowed::lowercase, FnInStruct)]
    112        #[diplomat::rust_link(
    113            icu::casemap::CaseMapperBorrowed::lowercase_to_string,
    114            FnInStruct,
    115            hidden
    116        )]
    117        #[cfg(feature = "compiled_data")]
    118        pub fn lowercase_with_compiled_data(s: &str, locale: &Locale, write: &mut DiplomatWrite) {
    119            let _infallible = icu_casemap::CaseMapper::new()
    120                .lowercase(s, &locale.0.id)
    121                .write_to(write);
    122        }
    123 
    124        /// Returns the full uppercase mapping of the given string, using compiled data (avoids having to allocate a CaseMapper object)
    125        #[diplomat::rust_link(icu::casemap::CaseMapperBorrowed::uppercase, FnInStruct)]
    126        #[diplomat::rust_link(
    127            icu::casemap::CaseMapperBorrowed::uppercase_to_string,
    128            FnInStruct,
    129            hidden
    130        )]
    131        #[cfg(feature = "compiled_data")]
    132        pub fn uppercase_with_compiled_data(s: &str, locale: &Locale, write: &mut DiplomatWrite) {
    133            let _infallible = icu_casemap::CaseMapper::new()
    134                .uppercase(s, &locale.0.id)
    135                .write_to(write);
    136        }
    137 
    138        /// Returns the full titlecase mapping of the given string, performing head adjustment without
    139        /// loading additional data.
    140        /// (if head adjustment is enabled in the options)
    141        ///
    142        /// The `v1` refers to the version of the options struct, which may change as we add more options
    143        #[diplomat::rust_link(
    144            icu::casemap::CaseMapperBorrowed::titlecase_segment_with_only_case_data,
    145            FnInStruct
    146        )]
    147        #[diplomat::rust_link(
    148            icu::casemap::CaseMapperBorrowed::titlecase_segment_with_only_case_data_to_string,
    149            FnInStruct,
    150            hidden
    151        )]
    152        #[diplomat::attr(supports = non_exhaustive_structs, rename = "titlecase_segment_with_only_case_data")]
    153        pub fn titlecase_segment_with_only_case_data_v1(
    154            &self,
    155            s: &str,
    156            locale: &Locale,
    157            options: TitlecaseOptionsV1,
    158            write: &mut DiplomatWrite,
    159        ) {
    160            let _infallible = self
    161                .0
    162                .as_borrowed()
    163                .titlecase_segment_with_only_case_data(s, &locale.0.id, options.into())
    164                .write_to(write);
    165        }
    166 
    167        /// Case-folds the characters in the given string
    168        #[diplomat::rust_link(icu::casemap::CaseMapperBorrowed::fold, FnInStruct)]
    169        #[diplomat::rust_link(icu::casemap::CaseMapperBorrowed::fold_string, FnInStruct, hidden)]
    170        pub fn fold(&self, s: &str, write: &mut DiplomatWrite) {
    171            let _infallible = self.0.as_borrowed().fold(s).write_to(write);
    172        }
    173        /// Case-folds the characters in the given string
    174        /// using Turkic (T) mappings for dotted/dotless I.
    175        #[diplomat::rust_link(icu::casemap::CaseMapperBorrowed::fold_turkic, FnInStruct)]
    176        #[diplomat::rust_link(
    177            icu::casemap::CaseMapperBorrowed::fold_turkic_string,
    178            FnInStruct,
    179            hidden
    180        )]
    181        pub fn fold_turkic(&self, s: &str, write: &mut DiplomatWrite) {
    182            let _infallible = self.0.as_borrowed().fold_turkic(s).write_to(write);
    183        }
    184 
    185        /// Adds all simple case mappings and the full case folding for `c` to `builder`.
    186        /// Also adds special case closure mappings.
    187        ///
    188        /// In other words, this adds all characters that this casemaps to, as
    189        /// well as all characters that may casemap to this one.
    190        ///
    191        /// Note that since CodePointSetBuilder does not contain strings, this will
    192        /// ignore string mappings.
    193        ///
    194        /// Identical to the similarly named method on `CaseMapCloser`, use that if you
    195        /// plan on using string case closure mappings too.
    196        #[cfg(feature = "properties")]
    197        #[diplomat::rust_link(icu::casemap::CaseMapperBorrowed::add_case_closure_to, FnInStruct)]
    198        #[diplomat::rust_link(icu::casemap::ClosureSink, Trait, hidden)]
    199        #[diplomat::rust_link(icu::casemap::ClosureSink::add_char, FnInTrait, hidden)]
    200        #[diplomat::rust_link(icu::casemap::ClosureSink::add_string, FnInTrait, hidden)]
    201        pub fn add_case_closure_to(
    202            &self,
    203            c: DiplomatChar,
    204            builder: &mut crate::unstable::collections_sets::ffi::CodePointSetBuilder,
    205        ) {
    206            if let Some(ch) = char::from_u32(c) {
    207                self.0.as_borrowed().add_case_closure_to(ch, &mut builder.0)
    208            }
    209        }
    210 
    211        /// Returns the simple lowercase mapping of the given character.
    212        ///
    213        /// This function only implements simple and common mappings.
    214        /// Full mappings, which can map one char to a string, are not included.
    215        /// For full mappings, use `CaseMapperBorrowed::lowercase`.
    216        #[diplomat::rust_link(icu::casemap::CaseMapperBorrowed::simple_lowercase, FnInStruct)]
    217        pub fn simple_lowercase(&self, ch: DiplomatChar) -> DiplomatChar {
    218            char::from_u32(ch)
    219                .map(|ch| self.0.as_borrowed().simple_lowercase(ch) as DiplomatChar)
    220                .unwrap_or(ch)
    221        }
    222 
    223        /// Returns the simple uppercase mapping of the given character.
    224        ///
    225        /// This function only implements simple and common mappings.
    226        /// Full mappings, which can map one char to a string, are not included.
    227        /// For full mappings, use `CaseMapperBorrowed::uppercase`.
    228        #[diplomat::rust_link(icu::casemap::CaseMapperBorrowed::simple_uppercase, FnInStruct)]
    229        pub fn simple_uppercase(&self, ch: DiplomatChar) -> DiplomatChar {
    230            char::from_u32(ch)
    231                .map(|ch| self.0.as_borrowed().simple_uppercase(ch) as DiplomatChar)
    232                .unwrap_or(ch)
    233        }
    234 
    235        /// Returns the simple titlecase mapping of the given character.
    236        ///
    237        /// This function only implements simple and common mappings.
    238        /// Full mappings, which can map one char to a string, are not included.
    239        /// For full mappings, use `CaseMapperBorrowed::titlecase_segment`.
    240        #[diplomat::rust_link(icu::casemap::CaseMapperBorrowed::simple_titlecase, FnInStruct)]
    241        pub fn simple_titlecase(&self, ch: DiplomatChar) -> DiplomatChar {
    242            char::from_u32(ch)
    243                .map(|ch| self.0.as_borrowed().simple_titlecase(ch) as DiplomatChar)
    244                .unwrap_or(ch)
    245        }
    246 
    247        /// Returns the simple casefolding of the given character.
    248        ///
    249        /// This function only implements simple folding.
    250        /// For full folding, use `CaseMapperBorrowed::fold`.
    251        #[diplomat::rust_link(icu::casemap::CaseMapperBorrowed::simple_fold, FnInStruct)]
    252        pub fn simple_fold(&self, ch: DiplomatChar) -> DiplomatChar {
    253            char::from_u32(ch)
    254                .map(|ch| self.0.as_borrowed().simple_fold(ch) as DiplomatChar)
    255                .unwrap_or(ch)
    256        }
    257        /// Returns the simple casefolding of the given character in the Turkic locale
    258        ///
    259        /// This function only implements simple folding.
    260        /// For full folding, use `CaseMapperBorrowed::fold_turkic`.
    261        #[diplomat::rust_link(icu::casemap::CaseMapperBorrowed::simple_fold_turkic, FnInStruct)]
    262        pub fn simple_fold_turkic(&self, ch: DiplomatChar) -> DiplomatChar {
    263            char::from_u32(ch)
    264                .map(|ch| self.0.as_borrowed().simple_fold_turkic(ch) as DiplomatChar)
    265                .unwrap_or(ch)
    266        }
    267    }
    268 
    269    #[diplomat::opaque]
    270    #[diplomat::rust_link(icu::casemap::CaseMapCloser, Struct)]
    271    #[diplomat::rust_link(icu::casemap::CaseMapCloserBorrowed, Struct, hidden)]
    272    pub struct CaseMapCloser(pub icu_casemap::CaseMapCloser<icu_casemap::CaseMapper>);
    273 
    274    impl CaseMapCloser {
    275        /// Construct a new CaseMapCloser instance using compiled data.
    276        #[diplomat::rust_link(icu::casemap::CaseMapCloser::new, FnInStruct)]
    277        #[diplomat::rust_link(icu::casemap::CaseMapCloserBorrowed::new, FnInStruct, hidden)]
    278        #[diplomat::rust_link(icu::casemap::CaseMapCloser::new_with_mapper, FnInStruct, hidden)]
    279        #[diplomat::attr(supports = "fallible_constructors", constructor)]
    280        #[cfg(feature = "compiled_data")]
    281        pub fn create() -> Result<Box<CaseMapCloser>, DataError> {
    282            Ok(Box::new(CaseMapCloser(
    283                icu_casemap::CaseMapCloser::new().static_to_owned(),
    284            )))
    285        }
    286        /// Construct a new CaseMapCloser instance using a particular data source.
    287        #[diplomat::rust_link(icu::casemap::CaseMapCloser::new, FnInStruct)]
    288        #[diplomat::rust_link(icu::casemap::CaseMapCloser::new_with_mapper, FnInStruct, hidden)]
    289        #[diplomat::attr(all(supports = fallible_constructors, supports = named_constructors), named_constructor = "with_provider")]
    290        #[cfg(feature = "buffer_provider")]
    291        pub fn create_with_provider(
    292            provider: &DataProvider,
    293        ) -> Result<Box<CaseMapCloser>, DataError> {
    294            Ok(Box::new(CaseMapCloser(
    295                icu_casemap::CaseMapCloser::try_new_with_buffer_provider(provider.get()?)?,
    296            )))
    297        }
    298        /// Adds all simple case mappings and the full case folding for `c` to `builder`.
    299        /// Also adds special case closure mappings.
    300        #[cfg(feature = "properties")]
    301        #[diplomat::rust_link(icu::casemap::CaseMapCloserBorrowed::add_case_closure_to, FnInStruct)]
    302        pub fn add_case_closure_to(
    303            &self,
    304            c: DiplomatChar,
    305            builder: &mut crate::unstable::collections_sets::ffi::CodePointSetBuilder,
    306        ) {
    307            if let Some(ch) = char::from_u32(c) {
    308                self.0.as_borrowed().add_case_closure_to(ch, &mut builder.0)
    309            }
    310        }
    311 
    312        /// Finds all characters and strings which may casemap to `s` as their full case folding string
    313        /// and adds them to the set.
    314        ///
    315        /// Returns true if the string was found
    316        #[cfg(feature = "properties")]
    317        #[diplomat::rust_link(
    318            icu::casemap::CaseMapCloserBorrowed::add_string_case_closure_to,
    319            FnInStruct
    320        )]
    321        pub fn add_string_case_closure_to(
    322            &self,
    323            s: &DiplomatStr,
    324            builder: &mut crate::unstable::collections_sets::ffi::CodePointSetBuilder,
    325        ) -> bool {
    326            let s = core::str::from_utf8(s).unwrap_or("");
    327            self.0
    328                .as_borrowed()
    329                .add_string_case_closure_to(s, &mut builder.0)
    330        }
    331    }
    332 
    333    #[diplomat::opaque]
    334    #[diplomat::rust_link(icu::casemap::TitlecaseMapper, Struct)]
    335    #[diplomat::rust_link(icu::casemap::TitlecaseMapperBorrowed, Struct, hidden)]
    336    pub struct TitlecaseMapper(pub icu_casemap::TitlecaseMapper<icu_casemap::CaseMapper>);
    337 
    338    impl TitlecaseMapper {
    339        /// Construct a new `TitlecaseMapper` instance using compiled data.
    340        #[diplomat::rust_link(icu::casemap::TitlecaseMapper::new, FnInStruct)]
    341        #[diplomat::rust_link(icu::casemap::TitlecaseMapperBorrowed::new, FnInStruct, hidden)]
    342        #[diplomat::rust_link(icu::casemap::TitlecaseMapper::new_with_mapper, FnInStruct, hidden)]
    343        #[diplomat::attr(supports = "fallible_constructors", constructor)]
    344        #[cfg(feature = "compiled_data")]
    345        pub fn create() -> Result<Box<TitlecaseMapper>, DataError> {
    346            Ok(Box::new(TitlecaseMapper(
    347                icu_casemap::TitlecaseMapper::new().static_to_owned(),
    348            )))
    349        }
    350        /// Construct a new `TitlecaseMapper` instance using a particular data source.
    351        #[diplomat::rust_link(icu::casemap::TitlecaseMapper::new, FnInStruct)]
    352        #[diplomat::rust_link(icu::casemap::TitlecaseMapper::new_with_mapper, FnInStruct, hidden)]
    353        #[diplomat::attr(all(supports = fallible_constructors, supports = named_constructors), named_constructor = "with_provider")]
    354        #[cfg(feature = "buffer_provider")]
    355        pub fn create_with_provider(
    356            provider: &DataProvider,
    357        ) -> Result<Box<TitlecaseMapper>, DataError> {
    358            Ok(Box::new(TitlecaseMapper(
    359                icu_casemap::TitlecaseMapper::try_new_with_buffer_provider(provider.get()?)?,
    360            )))
    361        }
    362        /// Returns the full titlecase mapping of the given string
    363        ///
    364        /// The `v1` refers to the version of the options struct, which may change as we add more options
    365        #[diplomat::rust_link(icu::casemap::TitlecaseMapperBorrowed::titlecase_segment, FnInStruct)]
    366        #[diplomat::rust_link(
    367            icu::casemap::TitlecaseMapperBorrowed::titlecase_segment_to_string,
    368            FnInStruct,
    369            hidden
    370        )]
    371        #[diplomat::attr(supports = non_exhaustive_structs, rename = "titlecase_segment")]
    372        pub fn titlecase_segment_v1(
    373            &self,
    374            s: &str,
    375            locale: &Locale,
    376            options: TitlecaseOptionsV1,
    377            write: &mut DiplomatWrite,
    378        ) {
    379            let _infallible = self
    380                .0
    381                .as_borrowed()
    382                .titlecase_segment(s, &locale.0.id, options.into())
    383                .write_to(write);
    384        }
    385        /// Returns the full titlecase mapping of the given string, using compiled data (avoids having to allocate a TitlecaseMapper object)
    386        ///
    387        /// The `v1` refers to the version of the options struct, which may change as we add more options
    388        #[diplomat::rust_link(icu::casemap::TitlecaseMapperBorrowed::titlecase_segment, FnInStruct)]
    389        #[diplomat::rust_link(
    390            icu::casemap::TitlecaseMapperBorrowed::titlecase_segment_to_string,
    391            FnInStruct,
    392            hidden
    393        )]
    394        #[diplomat::attr(supports = non_exhaustive_structs, rename = "titlecase_segment_with_compiled_data")]
    395        #[cfg(feature = "compiled_data")]
    396        pub fn titlecase_segment_with_compiled_data_v1(
    397            s: &str,
    398            locale: &Locale,
    399            options: TitlecaseOptionsV1,
    400            write: &mut DiplomatWrite,
    401        ) {
    402            let _infallible = icu_casemap::TitlecaseMapper::new()
    403                .titlecase_segment(s, &locale.0.id, options.into())
    404                .write_to(write);
    405        }
    406    }
    407 }
    408 
    409 impl From<ffi::TitlecaseOptionsV1> for TitlecaseOptions {
    410    fn from(other: ffi::TitlecaseOptionsV1) -> Self {
    411        let mut ret = Self::default();
    412 
    413        ret.leading_adjustment = other.leading_adjustment.into_converted_option();
    414 
    415        ret.trailing_case = other.trailing_case.into_converted_option();
    416 
    417        ret
    418    }
    419 }