• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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::errors::ffi::DataError;
15     use crate::locale_core::ffi::Locale;
16     #[cfg(feature = "buffer_provider")]
17     use crate::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")]
default() -> TitlecaseOptionsV148         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")]
create() -> Box<CaseMapper>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")]
create_with_provider(provider: &DataProvider) -> Result<Box<CaseMapper>, DataError>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         )]
lowercase(&self, s: &str, locale: &Locale, write: &mut DiplomatWrite)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         )]
uppercase(&self, s: &str, locale: &Locale, write: &mut DiplomatWrite)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 titlecase mapping of the given string, performing head adjustment without
111         /// loading additional data.
112         /// (if head adjustment is enabled in the options)
113         ///
114         /// The `v1` refers to the version of the options struct, which may change as we add more options
115         #[diplomat::rust_link(
116             icu::casemap::CaseMapperBorrowed::titlecase_segment_with_only_case_data,
117             FnInStruct
118         )]
119         #[diplomat::rust_link(
120             icu::casemap::CaseMapperBorrowed::titlecase_segment_with_only_case_data_to_string,
121             FnInStruct,
122             hidden
123         )]
124         #[diplomat::attr(supports = non_exhaustive_structs, rename = "titlecase_segment_with_only_case_data")]
titlecase_segment_with_only_case_data_v1( &self, s: &str, locale: &Locale, options: TitlecaseOptionsV1, write: &mut DiplomatWrite, )125         pub fn titlecase_segment_with_only_case_data_v1(
126             &self,
127             s: &str,
128             locale: &Locale,
129             options: TitlecaseOptionsV1,
130             write: &mut DiplomatWrite,
131         ) {
132             let _infallible = self
133                 .0
134                 .as_borrowed()
135                 .titlecase_segment_with_only_case_data(s, &locale.0.id, options.into())
136                 .write_to(write);
137         }
138 
139         /// Case-folds the characters in the given string
140         #[diplomat::rust_link(icu::casemap::CaseMapperBorrowed::fold, FnInStruct)]
141         #[diplomat::rust_link(icu::casemap::CaseMapperBorrowed::fold_string, FnInStruct, hidden)]
fold(&self, s: &str, write: &mut DiplomatWrite)142         pub fn fold(&self, s: &str, write: &mut DiplomatWrite) {
143             let _infallible = self.0.as_borrowed().fold(s).write_to(write);
144         }
145         /// Case-folds the characters in the given string
146         /// using Turkic (T) mappings for dotted/dotless I.
147         #[diplomat::rust_link(icu::casemap::CaseMapperBorrowed::fold_turkic, FnInStruct)]
148         #[diplomat::rust_link(
149             icu::casemap::CaseMapperBorrowed::fold_turkic_string,
150             FnInStruct,
151             hidden
152         )]
fold_turkic(&self, s: &str, write: &mut DiplomatWrite)153         pub fn fold_turkic(&self, s: &str, write: &mut DiplomatWrite) {
154             let _infallible = self.0.as_borrowed().fold_turkic(s).write_to(write);
155         }
156 
157         /// Adds all simple case mappings and the full case folding for `c` to `builder`.
158         /// Also adds special case closure mappings.
159         ///
160         /// In other words, this adds all characters that this casemaps to, as
161         /// well as all characters that may casemap to this one.
162         ///
163         /// Note that since CodePointSetBuilder does not contain strings, this will
164         /// ignore string mappings.
165         ///
166         /// Identical to the similarly named method on `CaseMapCloser`, use that if you
167         /// plan on using string case closure mappings too.
168         #[cfg(feature = "properties")]
169         #[diplomat::rust_link(icu::casemap::CaseMapperBorrowed::add_case_closure_to, FnInStruct)]
170         #[diplomat::rust_link(icu::casemap::ClosureSink, Trait, hidden)]
171         #[diplomat::rust_link(icu::casemap::ClosureSink::add_char, FnInTrait, hidden)]
172         #[diplomat::rust_link(icu::casemap::ClosureSink::add_string, FnInTrait, hidden)]
add_case_closure_to( &self, c: DiplomatChar, builder: &mut crate::collections_sets::ffi::CodePointSetBuilder, )173         pub fn add_case_closure_to(
174             &self,
175             c: DiplomatChar,
176             builder: &mut crate::collections_sets::ffi::CodePointSetBuilder,
177         ) {
178             if let Some(ch) = char::from_u32(c) {
179                 self.0.as_borrowed().add_case_closure_to(ch, &mut builder.0)
180             }
181         }
182 
183         /// Returns the simple lowercase mapping of the given character.
184         ///
185         /// This function only implements simple and common mappings.
186         /// Full mappings, which can map one char to a string, are not included.
187         /// For full mappings, use `CaseMapperBorrowed::lowercase`.
188         #[diplomat::rust_link(icu::casemap::CaseMapperBorrowed::simple_lowercase, FnInStruct)]
simple_lowercase(&self, ch: DiplomatChar) -> DiplomatChar189         pub fn simple_lowercase(&self, ch: DiplomatChar) -> DiplomatChar {
190             char::from_u32(ch)
191                 .map(|ch| self.0.as_borrowed().simple_lowercase(ch) as DiplomatChar)
192                 .unwrap_or(ch)
193         }
194 
195         /// Returns the simple uppercase mapping of the given character.
196         ///
197         /// This function only implements simple and common mappings.
198         /// Full mappings, which can map one char to a string, are not included.
199         /// For full mappings, use `CaseMapperBorrowed::uppercase`.
200         #[diplomat::rust_link(icu::casemap::CaseMapperBorrowed::simple_uppercase, FnInStruct)]
simple_uppercase(&self, ch: DiplomatChar) -> DiplomatChar201         pub fn simple_uppercase(&self, ch: DiplomatChar) -> DiplomatChar {
202             char::from_u32(ch)
203                 .map(|ch| self.0.as_borrowed().simple_uppercase(ch) as DiplomatChar)
204                 .unwrap_or(ch)
205         }
206 
207         /// Returns the simple titlecase mapping of the given character.
208         ///
209         /// This function only implements simple and common mappings.
210         /// Full mappings, which can map one char to a string, are not included.
211         /// For full mappings, use `CaseMapperBorrowed::titlecase_segment`.
212         #[diplomat::rust_link(icu::casemap::CaseMapperBorrowed::simple_titlecase, FnInStruct)]
simple_titlecase(&self, ch: DiplomatChar) -> DiplomatChar213         pub fn simple_titlecase(&self, ch: DiplomatChar) -> DiplomatChar {
214             char::from_u32(ch)
215                 .map(|ch| self.0.as_borrowed().simple_titlecase(ch) as DiplomatChar)
216                 .unwrap_or(ch)
217         }
218 
219         /// Returns the simple casefolding of the given character.
220         ///
221         /// This function only implements simple folding.
222         /// For full folding, use `CaseMapperBorrowed::fold`.
223         #[diplomat::rust_link(icu::casemap::CaseMapperBorrowed::simple_fold, FnInStruct)]
simple_fold(&self, ch: DiplomatChar) -> DiplomatChar224         pub fn simple_fold(&self, ch: DiplomatChar) -> DiplomatChar {
225             char::from_u32(ch)
226                 .map(|ch| self.0.as_borrowed().simple_fold(ch) as DiplomatChar)
227                 .unwrap_or(ch)
228         }
229         /// Returns the simple casefolding of the given character in the Turkic locale
230         ///
231         /// This function only implements simple folding.
232         /// For full folding, use `CaseMapperBorrowed::fold_turkic`.
233         #[diplomat::rust_link(icu::casemap::CaseMapperBorrowed::simple_fold_turkic, FnInStruct)]
simple_fold_turkic(&self, ch: DiplomatChar) -> DiplomatChar234         pub fn simple_fold_turkic(&self, ch: DiplomatChar) -> DiplomatChar {
235             char::from_u32(ch)
236                 .map(|ch| self.0.as_borrowed().simple_fold_turkic(ch) as DiplomatChar)
237                 .unwrap_or(ch)
238         }
239     }
240 
241     #[diplomat::opaque]
242     #[diplomat::rust_link(icu::casemap::CaseMapCloser, Struct)]
243     #[diplomat::rust_link(icu::casemap::CaseMapCloserBorrowed, Struct, hidden)]
244     pub struct CaseMapCloser(pub icu_casemap::CaseMapCloser<icu_casemap::CaseMapper>);
245 
246     impl CaseMapCloser {
247         /// Construct a new CaseMapCloser instance using compiled data.
248         #[diplomat::rust_link(icu::casemap::CaseMapCloser::new, FnInStruct)]
249         #[diplomat::rust_link(icu::casemap::CaseMapCloserBorrowed::new, FnInStruct, hidden)]
250         #[diplomat::rust_link(icu::casemap::CaseMapCloser::new_with_mapper, FnInStruct, hidden)]
251         #[diplomat::attr(supports = "fallible_constructors", constructor)]
252         #[cfg(feature = "compiled_data")]
create() -> Result<Box<CaseMapCloser>, DataError>253         pub fn create() -> Result<Box<CaseMapCloser>, DataError> {
254             Ok(Box::new(CaseMapCloser(
255                 icu_casemap::CaseMapCloser::new().static_to_owned(),
256             )))
257         }
258         /// Construct a new CaseMapCloser instance using a particular data source.
259         #[diplomat::rust_link(icu::casemap::CaseMapCloser::new, FnInStruct)]
260         #[diplomat::rust_link(icu::casemap::CaseMapCloser::new_with_mapper, FnInStruct, hidden)]
261         #[diplomat::attr(all(supports = fallible_constructors, supports = named_constructors), named_constructor = "with_provider")]
262         #[cfg(feature = "buffer_provider")]
create_with_provider( provider: &DataProvider, ) -> Result<Box<CaseMapCloser>, DataError>263         pub fn create_with_provider(
264             provider: &DataProvider,
265         ) -> Result<Box<CaseMapCloser>, DataError> {
266             Ok(Box::new(CaseMapCloser(
267                 icu_casemap::CaseMapCloser::try_new_with_buffer_provider(provider.get()?)?,
268             )))
269         }
270         /// Adds all simple case mappings and the full case folding for `c` to `builder`.
271         /// Also adds special case closure mappings.
272         #[cfg(feature = "properties")]
273         #[diplomat::rust_link(icu::casemap::CaseMapCloserBorrowed::add_case_closure_to, FnInStruct)]
add_case_closure_to( &self, c: DiplomatChar, builder: &mut crate::collections_sets::ffi::CodePointSetBuilder, )274         pub fn add_case_closure_to(
275             &self,
276             c: DiplomatChar,
277             builder: &mut crate::collections_sets::ffi::CodePointSetBuilder,
278         ) {
279             if let Some(ch) = char::from_u32(c) {
280                 self.0.as_borrowed().add_case_closure_to(ch, &mut builder.0)
281             }
282         }
283 
284         /// Finds all characters and strings which may casemap to `s` as their full case folding string
285         /// and adds them to the set.
286         ///
287         /// Returns true if the string was found
288         #[cfg(feature = "properties")]
289         #[diplomat::rust_link(
290             icu::casemap::CaseMapCloserBorrowed::add_string_case_closure_to,
291             FnInStruct
292         )]
add_string_case_closure_to( &self, s: &DiplomatStr, builder: &mut crate::collections_sets::ffi::CodePointSetBuilder, ) -> bool293         pub fn add_string_case_closure_to(
294             &self,
295             s: &DiplomatStr,
296             builder: &mut crate::collections_sets::ffi::CodePointSetBuilder,
297         ) -> bool {
298             let s = core::str::from_utf8(s).unwrap_or("");
299             self.0
300                 .as_borrowed()
301                 .add_string_case_closure_to(s, &mut builder.0)
302         }
303     }
304 
305     #[diplomat::opaque]
306     #[diplomat::rust_link(icu::casemap::TitlecaseMapper, Struct)]
307     #[diplomat::rust_link(icu::casemap::TitlecaseMapperBorrowed, Struct, hidden)]
308     pub struct TitlecaseMapper(pub icu_casemap::TitlecaseMapper<icu_casemap::CaseMapper>);
309 
310     impl TitlecaseMapper {
311         /// Construct a new `TitlecaseMapper` instance using compiled data.
312         #[diplomat::rust_link(icu::casemap::TitlecaseMapper::new, FnInStruct)]
313         #[diplomat::rust_link(icu::casemap::TitlecaseMapperBorrowed::new, FnInStruct, hidden)]
314         #[diplomat::rust_link(icu::casemap::TitlecaseMapper::new_with_mapper, FnInStruct, hidden)]
315         #[diplomat::attr(supports = "fallible_constructors", constructor)]
316         #[cfg(feature = "compiled_data")]
create() -> Result<Box<TitlecaseMapper>, DataError>317         pub fn create() -> Result<Box<TitlecaseMapper>, DataError> {
318             Ok(Box::new(TitlecaseMapper(
319                 icu_casemap::TitlecaseMapper::new().static_to_owned(),
320             )))
321         }
322         /// Construct a new `TitlecaseMapper` instance using a particular data source.
323         #[diplomat::rust_link(icu::casemap::TitlecaseMapper::new, FnInStruct)]
324         #[diplomat::rust_link(icu::casemap::TitlecaseMapper::new_with_mapper, FnInStruct, hidden)]
325         #[diplomat::attr(all(supports = fallible_constructors, supports = named_constructors), named_constructor = "with_provider")]
326         #[cfg(feature = "buffer_provider")]
create_with_provider( provider: &DataProvider, ) -> Result<Box<TitlecaseMapper>, DataError>327         pub fn create_with_provider(
328             provider: &DataProvider,
329         ) -> Result<Box<TitlecaseMapper>, DataError> {
330             Ok(Box::new(TitlecaseMapper(
331                 icu_casemap::TitlecaseMapper::try_new_with_buffer_provider(provider.get()?)?,
332             )))
333         }
334         /// Returns the full titlecase mapping of the given string
335         ///
336         /// The `v1` refers to the version of the options struct, which may change as we add more options
337         #[diplomat::rust_link(icu::casemap::TitlecaseMapperBorrowed::titlecase_segment, FnInStruct)]
338         #[diplomat::rust_link(
339             icu::casemap::TitlecaseMapperBorrowed::titlecase_segment_to_string,
340             FnInStruct,
341             hidden
342         )]
343         #[diplomat::attr(supports = non_exhaustive_structs, rename = "titlecase_segment")]
titlecase_segment_v1( &self, s: &str, locale: &Locale, options: TitlecaseOptionsV1, write: &mut DiplomatWrite, )344         pub fn titlecase_segment_v1(
345             &self,
346             s: &str,
347             locale: &Locale,
348             options: TitlecaseOptionsV1,
349             write: &mut DiplomatWrite,
350         ) {
351             let _infallible = self
352                 .0
353                 .as_borrowed()
354                 .titlecase_segment(s, &locale.0.id, options.into())
355                 .write_to(write);
356         }
357     }
358 }
359 
360 impl From<ffi::TitlecaseOptionsV1> for TitlecaseOptions {
from(other: ffi::TitlecaseOptionsV1) -> Self361     fn from(other: ffi::TitlecaseOptionsV1) -> Self {
362         let mut ret = Self::default();
363 
364         ret.leading_adjustment = other.leading_adjustment.into_converted_option();
365 
366         ret.trailing_case = other.trailing_case.into_converted_option();
367 
368         ret
369     }
370 }
371