Backed out changeset 2450366cf7ca (bug 1891629) for causing win msix mochitest failures
[gecko.git] / intl / icu_capi / src / properties_maps.rs
blob3d5cd6dfce79052636876911706f05506c5931b7
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 ).
5 #[diplomat::bridge]
6 pub mod ffi {
7     use crate::provider::ffi::ICU4XDataProvider;
8     use alloc::boxed::Box;
9     use icu_collections::codepointtrie::TrieValue;
10     use icu_properties::{maps, GeneralCategory, GeneralCategoryGroup};
12     use crate::errors::ffi::ICU4XError;
13     use crate::properties_iter::ffi::CodePointRangeIterator;
14     use crate::properties_sets::ffi::ICU4XCodePointSetData;
16     #[diplomat::opaque]
17     /// An ICU4X Unicode Map Property object, capable of querying whether a code point (key) to obtain the Unicode property value, for a specific Unicode property.
18     ///
19     /// For properties whose values fit into 8 bits.
20     #[diplomat::rust_link(icu::properties, Mod)]
21     #[diplomat::rust_link(icu::properties::maps::CodePointMapData, Struct)]
22     #[diplomat::rust_link(icu::properties::maps::CodePointMapData::from_data, FnInStruct, hidden)]
23     #[diplomat::rust_link(
24         icu::properties::maps::CodePointMapData::try_into_converted,
25         FnInStruct,
26         hidden
27     )]
28     #[diplomat::rust_link(icu::properties::maps::CodePointMapDataBorrowed, Struct)]
29     pub struct ICU4XCodePointMapData8(maps::CodePointMapData<u8>);
31     fn convert_8<P: TrieValue>(data: maps::CodePointMapData<P>) -> Box<ICU4XCodePointMapData8> {
32         #[allow(clippy::expect_used)] // infallible for the chosen properties
33         Box::new(ICU4XCodePointMapData8(
34             data.try_into_converted()
35                 .expect("try_into_converted to u8 must be infallible"),
36         ))
37     }
39     impl ICU4XCodePointMapData8 {
40         /// Gets the value for a code point.
41         #[diplomat::rust_link(icu::properties::maps::CodePointMapDataBorrowed::get, FnInStruct)]
42         pub fn get(&self, cp: char) -> u8 {
43             self.0.as_borrowed().get(cp)
44         }
46         /// Gets the value for a code point (specified as a 32 bit integer, in UTF-32)
47         #[diplomat::rust_link(
48             icu::properties::maps::CodePointMapDataBorrowed::get32,
49             FnInStruct,
50             hidden
51         )]
52         pub fn get32(&self, cp: u32) -> u8 {
53             self.0.as_borrowed().get32(cp)
54         }
56         /// Converts a general category to its corresponding mask value
57         ///
58         /// Nonexistant general categories will map to the empty mask
59         #[diplomat::rust_link(icu::properties::GeneralCategoryGroup, Struct)]
60         pub fn general_category_to_mask(gc: u8) -> u32 {
61             if let Ok(gc) = GeneralCategory::try_from(gc) {
62                 let group: GeneralCategoryGroup = gc.into();
63                 group.into()
64             } else {
65                 0
66             }
67         }
69         /// Produces an iterator over ranges of code points that map to `value`
70         #[diplomat::rust_link(
71             icu::properties::maps::CodePointMapDataBorrowed::iter_ranges_for_value,
72             FnInStruct
73         )]
74         pub fn iter_ranges_for_value<'a>(&'a self, value: u8) -> Box<CodePointRangeIterator<'a>> {
75             Box::new(CodePointRangeIterator(Box::new(
76                 self.0.as_borrowed().iter_ranges_for_value(value),
77             )))
78         }
80         /// Produces an iterator over ranges of code points that do not map to `value`
81         #[diplomat::rust_link(
82             icu::properties::maps::CodePointMapDataBorrowed::iter_ranges_for_value_complemented,
83             FnInStruct
84         )]
85         pub fn iter_ranges_for_value_complemented<'a>(
86             &'a self,
87             value: u8,
88         ) -> Box<CodePointRangeIterator<'a>> {
89             Box::new(CodePointRangeIterator(Box::new(
90                 self.0
91                     .as_borrowed()
92                     .iter_ranges_for_value_complemented(value),
93             )))
94         }
96         /// Given a mask value (the nth bit marks property value = n), produce an iterator over ranges of code points
97         /// whose property values are contained in the mask.
98         ///
99         /// The main mask property supported is that for General_Category, which can be obtained via `general_category_to_mask()` or
100         /// by using `ICU4XGeneralCategoryNameToMaskMapper`
101         ///
102         /// Should only be used on maps for properties with values less than 32 (like Generak_Category),
103         /// other maps will have unpredictable results
104         #[diplomat::rust_link(
105             icu::properties::maps::CodePointMapDataBorrowed::iter_ranges_for_group,
106             FnInStruct
107         )]
108         pub fn iter_ranges_for_mask<'a>(&'a self, mask: u32) -> Box<CodePointRangeIterator<'a>> {
109             let ranges = self
110                 .0
111                 .as_borrowed()
112                 .iter_ranges_mapped(move |v| {
113                     let val_mask = 1_u32.checked_shl(v.into()).unwrap_or(0);
114                     val_mask & mask != 0
115                 })
116                 .filter(|v| v.value)
117                 .map(|v| v.range);
118             Box::new(CodePointRangeIterator(Box::new(ranges)))
119         }
121         /// Gets a [`ICU4XCodePointSetData`] representing all entries in this map that map to the given value
122         #[diplomat::rust_link(
123             icu::properties::maps::CodePointMapDataBorrowed::get_set_for_value,
124             FnInStruct
125         )]
126         pub fn get_set_for_value(&self, value: u8) -> Box<ICU4XCodePointSetData> {
127             Box::new(ICU4XCodePointSetData(
128                 self.0.as_borrowed().get_set_for_value(value),
129             ))
130         }
132         #[diplomat::rust_link(icu::properties::maps::general_category, Fn)]
133         #[diplomat::rust_link(icu::properties::maps::load_general_category, Fn, hidden)]
134         pub fn load_general_category(
135             provider: &ICU4XDataProvider,
136         ) -> Result<Box<ICU4XCodePointMapData8>, ICU4XError> {
137             Ok(convert_8(call_constructor_unstable!(
138                 maps::general_category [r => Ok(r.static_to_owned())],
139                 maps::load_general_category,
140                 provider,
141             )?))
142         }
144         #[diplomat::rust_link(icu::properties::maps::bidi_class, Fn)]
145         #[diplomat::rust_link(icu::properties::maps::load_bidi_class, Fn, hidden)]
146         pub fn load_bidi_class(
147             provider: &ICU4XDataProvider,
148         ) -> Result<Box<ICU4XCodePointMapData8>, ICU4XError> {
149             Ok(convert_8(call_constructor_unstable!(
150                 maps::bidi_class [r => Ok(r.static_to_owned())],
151                 maps::load_bidi_class,
152                 provider,
153             )?))
154         }
156         #[diplomat::rust_link(icu::properties::maps::east_asian_width, Fn)]
157         #[diplomat::rust_link(icu::properties::maps::load_east_asian_width, Fn, hidden)]
158         pub fn load_east_asian_width(
159             provider: &ICU4XDataProvider,
160         ) -> Result<Box<ICU4XCodePointMapData8>, ICU4XError> {
161             Ok(convert_8(call_constructor_unstable!(
162                 maps::east_asian_width [r => Ok(r.static_to_owned())],
163                 maps::load_east_asian_width,
164                 provider,
165             )?))
166         }
168         #[diplomat::rust_link(icu::properties::maps::indic_syllabic_category, Fn)]
169         #[diplomat::rust_link(icu::properties::maps::load_indic_syllabic_category, Fn, hidden)]
170         pub fn load_indic_syllabic_category(
171             provider: &ICU4XDataProvider,
172         ) -> Result<Box<ICU4XCodePointMapData8>, ICU4XError> {
173             Ok(convert_8(call_constructor_unstable!(
174                 maps::indic_syllabic_category [r => Ok(r.static_to_owned())],
175                 maps::load_indic_syllabic_category,
176                 provider,
177             )?))
178         }
180         #[diplomat::rust_link(icu::properties::maps::line_break, Fn)]
181         #[diplomat::rust_link(icu::properties::maps::load_line_break, Fn, hidden)]
182         pub fn load_line_break(
183             provider: &ICU4XDataProvider,
184         ) -> Result<Box<ICU4XCodePointMapData8>, ICU4XError> {
185             Ok(convert_8(call_constructor_unstable!(
186                 maps::line_break [r => Ok(r.static_to_owned())],
187                 maps::load_line_break,
188                 provider,
189             )?))
190         }
192         #[diplomat::rust_link(icu::properties::maps::grapheme_cluster_break, Fn)]
193         #[diplomat::rust_link(icu::properties::maps::load_grapheme_cluster_break, Fn, hidden)]
194         #[diplomat::attr(dart, rename = "grapheme_cluster_break")]
195         pub fn try_grapheme_cluster_break(
196             provider: &ICU4XDataProvider,
197         ) -> Result<Box<ICU4XCodePointMapData8>, ICU4XError> {
198             Ok(convert_8(call_constructor_unstable!(
199                 maps::grapheme_cluster_break [r => Ok(r.static_to_owned())],
200                 maps::load_grapheme_cluster_break,
201                 provider,
202             )?))
203         }
205         #[diplomat::rust_link(icu::properties::maps::word_break, Fn)]
206         #[diplomat::rust_link(icu::properties::maps::load_word_break, Fn, hidden)]
207         pub fn load_word_break(
208             provider: &ICU4XDataProvider,
209         ) -> Result<Box<ICU4XCodePointMapData8>, ICU4XError> {
210             Ok(convert_8(call_constructor_unstable!(
211                 maps::word_break [r => Ok(r.static_to_owned())],
212                 maps::load_word_break,
213                 provider,
214             )?))
215         }
217         #[diplomat::rust_link(icu::properties::maps::sentence_break, Fn)]
218         #[diplomat::rust_link(icu::properties::maps::load_sentence_break, Fn, hidden)]
219         pub fn load_sentence_break(
220             provider: &ICU4XDataProvider,
221         ) -> Result<Box<ICU4XCodePointMapData8>, ICU4XError> {
222             Ok(convert_8(call_constructor_unstable!(
223                 maps::sentence_break [r => Ok(r.static_to_owned())],
224                 maps::load_sentence_break,
225                 provider,
226             )?))
227         }
228     }
230     #[diplomat::opaque]
231     /// An ICU4X Unicode Map Property object, capable of querying whether a code point (key) to obtain the Unicode property value, for a specific Unicode property.
232     ///
233     /// For properties whose values fit into 16 bits.
234     #[diplomat::rust_link(icu::properties, Mod)]
235     #[diplomat::rust_link(icu::properties::maps::CodePointMapData, Struct)]
236     #[diplomat::rust_link(icu::properties::maps::CodePointMapDataBorrowed, Struct)]
237     pub struct ICU4XCodePointMapData16(maps::CodePointMapData<u16>);
239     impl ICU4XCodePointMapData16 {
240         /// Gets the value for a code point.
241         #[diplomat::rust_link(icu::properties::maps::CodePointMapDataBorrowed::get, FnInStruct)]
242         pub fn get(&self, cp: char) -> u16 {
243             self.0.as_borrowed().get(cp)
244         }
246         /// Gets the value for a code point (specified as a 32 bit integer, in UTF-32)
247         #[diplomat::rust_link(
248             icu::properties::maps::CodePointMapDataBorrowed::get32,
249             FnInStruct,
250             hidden
251         )]
252         pub fn get32(&self, cp: u32) -> u16 {
253             self.0.as_borrowed().get32(cp)
254         }
256         /// Produces an iterator over ranges of code points that map to `value`
257         #[diplomat::rust_link(
258             icu::properties::maps::CodePointMapDataBorrowed::iter_ranges_for_value,
259             FnInStruct
260         )]
261         pub fn iter_ranges_for_value<'a>(&'a self, value: u16) -> Box<CodePointRangeIterator<'a>> {
262             Box::new(CodePointRangeIterator(Box::new(
263                 self.0.as_borrowed().iter_ranges_for_value(value),
264             )))
265         }
267         /// Produces an iterator over ranges of code points that do not map to `value`
268         #[diplomat::rust_link(
269             icu::properties::maps::CodePointMapDataBorrowed::iter_ranges_for_value_complemented,
270             FnInStruct
271         )]
272         pub fn iter_ranges_for_value_complemented<'a>(
273             &'a self,
274             value: u16,
275         ) -> Box<CodePointRangeIterator<'a>> {
276             Box::new(CodePointRangeIterator(Box::new(
277                 self.0
278                     .as_borrowed()
279                     .iter_ranges_for_value_complemented(value),
280             )))
281         }
283         /// Gets a [`ICU4XCodePointSetData`] representing all entries in this map that map to the given value
284         #[diplomat::rust_link(
285             icu::properties::maps::CodePointMapDataBorrowed::get_set_for_value,
286             FnInStruct
287         )]
288         pub fn get_set_for_value(&self, value: u16) -> Box<ICU4XCodePointSetData> {
289             Box::new(ICU4XCodePointSetData(
290                 self.0.as_borrowed().get_set_for_value(value),
291             ))
292         }
294         #[diplomat::rust_link(icu::properties::maps::script, Fn)]
295         #[diplomat::rust_link(icu::properties::maps::load_script, Fn, hidden)]
296         pub fn load_script(
297             provider: &ICU4XDataProvider,
298         ) -> Result<Box<ICU4XCodePointMapData16>, ICU4XError> {
299             #[allow(clippy::expect_used)] // script is a 16-bit property
300             Ok(Box::new(ICU4XCodePointMapData16(
301                 call_constructor_unstable!(
302                     maps::script [r => Ok(r.static_to_owned())],
303                     maps::load_script,
304                     provider,
305                 )?
306                 .try_into_converted()
307                 .expect("try_into_converted to u16 must be infallible"),
308             )))
309         }
310     }