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 ).
7 use crate::provider::ffi::ICU4XDataProvider;
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;
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.
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,
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"),
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)
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,
52 pub fn get32(&self, cp: u32) -> u8 {
53 self.0.as_borrowed().get32(cp)
56 /// Converts a general category to its corresponding mask value
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();
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,
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),
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,
85 pub fn iter_ranges_for_value_complemented<'a>(
88 ) -> Box<CodePointRangeIterator<'a>> {
89 Box::new(CodePointRangeIterator(Box::new(
92 .iter_ranges_for_value_complemented(value),
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.
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`
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,
108 pub fn iter_ranges_for_mask<'a>(&'a self, mask: u32) -> Box<CodePointRangeIterator<'a>> {
112 .iter_ranges_mapped(move |v| {
113 let val_mask = 1_u32.checked_shl(v.into()).unwrap_or(0);
118 Box::new(CodePointRangeIterator(Box::new(ranges)))
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,
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),
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,
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,
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,
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,
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,
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,
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,
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,
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.
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)
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,
252 pub fn get32(&self, cp: u32) -> u16 {
253 self.0.as_borrowed().get32(cp)
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,
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),
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,
272 pub fn iter_ranges_for_value_complemented<'a>(
275 ) -> Box<CodePointRangeIterator<'a>> {
276 Box::new(CodePointRangeIterator(Box::new(
279 .iter_ranges_for_value_complemented(value),
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,
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),
294 #[diplomat::rust_link(icu::properties::maps::script, Fn)]
295 #[diplomat::rust_link(icu::properties::maps::load_script, Fn, hidden)]
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())],
306 .try_into_converted()
307 .expect("try_into_converted to u16 must be infallible"),