|
2 | 2 | // called LICENSE at the top level of the ICU4X source tree
|
3 | 3 | // (online at: https://github.com/unicode-org/icu4x/blob/main/LICENSE ).
|
4 | 4 |
|
5 |
| -//! Data and APIs for supporting specific Bidi properties data in an efficient structure. |
6 |
| -//! |
7 |
| -//! Supported properties are: |
8 |
| -//! - `Bidi_Paired_Bracket` |
9 |
| -//! - `Bidi_Paired_Bracket_Type` |
10 |
| -//! - `Bidi_Mirrored` |
11 |
| -//! - `Bidi_Mirroring_Glyph` |
12 |
| -
|
13 |
| -use crate::provider::bidi::{ |
14 |
| - BidiAuxiliaryPropertiesV1, BidiAuxiliaryPropertiesV1Marker, CheckedBidiPairedBracketType, |
15 |
| -}; |
16 |
| - |
17 |
| -use icu_provider::prelude::*; |
18 |
| - |
19 |
| -/// A wrapper around certain Bidi properties data. |
20 |
| -/// |
21 |
| -/// Most useful methods are on [`BidiAuxiliaryPropertiesBorrowed`] obtained by calling [`BidiAuxiliaryProperties::as_borrowed()`] |
22 |
| -#[derive(Debug)] |
23 |
| -pub struct BidiAuxiliaryProperties { |
24 |
| - data: DataPayload<BidiAuxiliaryPropertiesV1Marker>, |
25 |
| -} |
26 |
| - |
27 |
| -impl BidiAuxiliaryProperties { |
28 |
| - /// Creates a [`BidiAuxiliaryPropertiesV1`] struct that represents the data for certain |
29 |
| - /// Bidi properties. |
30 |
| - /// |
31 |
| - /// ✨ *Enabled with the `compiled_data` Cargo feature.* |
32 |
| - /// |
33 |
| - /// [📚 Help choosing a constructor](icu_provider::constructors) |
34 |
| - /// |
35 |
| - /// # Examples |
36 |
| - /// ``` |
37 |
| - /// use icu::properties::bidi::BidiAuxiliaryProperties; |
38 |
| - /// |
39 |
| - /// let bidi_data = BidiAuxiliaryProperties::new(); |
40 |
| - /// |
41 |
| - /// let open_paren = bidi_data.get32_mirroring_props('(' as u32); |
42 |
| - /// assert_eq!(open_paren.mirroring_glyph, Some(')')); |
43 |
| - /// assert_eq!(open_paren.mirrored, true); |
44 |
| - /// ``` |
45 |
| - #[cfg(feature = "compiled_data")] |
46 |
| - #[allow(clippy::new_ret_no_self)] |
47 |
| - pub const fn new() -> BidiAuxiliaryPropertiesBorrowed<'static> { |
48 |
| - BidiAuxiliaryPropertiesBorrowed { |
49 |
| - data: crate::provider::Baked::SINGLETON_BIDI_AUXILIARY_PROPERTIES_V1_MARKER, |
50 |
| - } |
51 |
| - } |
52 |
| - |
53 |
| - icu_provider::gen_any_buffer_data_constructors!( |
54 |
| - () -> result: Result<BidiAuxiliaryProperties, DataError>, |
55 |
| - functions: [ |
56 |
| - new: skip, |
57 |
| - try_new_with_any_provider, |
58 |
| - try_new_with_buffer_provider, |
59 |
| - try_new_unstable, |
60 |
| - Self |
61 |
| - ] |
62 |
| - ); |
63 |
| - |
64 |
| - #[doc = icu_provider::gen_any_buffer_unstable_docs!(UNSTABLE, Self::new)] |
65 |
| - pub fn try_new_unstable( |
66 |
| - provider: &(impl DataProvider<BidiAuxiliaryPropertiesV1Marker> + ?Sized), |
67 |
| - ) -> Result<BidiAuxiliaryProperties, DataError> { |
68 |
| - Ok(BidiAuxiliaryProperties::from_data( |
69 |
| - provider.load(Default::default())?.payload, |
70 |
| - )) |
71 |
| - } |
72 |
| - |
73 |
| - /// Construct a borrowed version of this type that can be queried. |
74 |
| - /// |
75 |
| - /// This avoids a potential small underlying cost per API call by consolidating it |
76 |
| - /// up front. |
77 |
| - #[inline] |
78 |
| - pub fn as_borrowed(&self) -> BidiAuxiliaryPropertiesBorrowed<'_> { |
79 |
| - BidiAuxiliaryPropertiesBorrowed { |
80 |
| - data: self.data.get(), |
81 |
| - } |
82 |
| - } |
83 |
| - |
84 |
| - /// Construct a new one from loaded data |
85 |
| - /// |
86 |
| - /// Typically it is preferable to use getters like [`bidi_auxiliary_properties()`] instead |
87 |
| - pub(crate) fn from_data(data: DataPayload<BidiAuxiliaryPropertiesV1Marker>) -> Self { |
88 |
| - Self { data } |
89 |
| - } |
90 |
| -} |
91 |
| - |
92 |
| -/// This struct represents the properties Bidi_Mirrored and Bidi_Mirroring_Glyph. |
93 |
| -/// If Bidi_Mirroring_Glyph is not defined for a code point, then the value in the |
94 |
| -/// struct is `None`. |
95 |
| -#[derive(Debug, Eq, PartialEq)] |
| 5 | +use crate::{props::EnumeratedProperty, provider::BidiMirroringGlyphV1Marker}; |
| 6 | +use icu_collections::codepointtrie::TrieValue; |
| 7 | +use zerovec::ule::{AsULE, RawBytesULE}; |
| 8 | + |
| 9 | +/// This is a bitpacked combination of the `Bidi_Mirroring_Glyph`, |
| 10 | +/// `Bidi_Mirrored`, and `Bidi_Paired_Bracket_Type` properties. |
| 11 | +#[derive(Debug, Eq, PartialEq, Clone, Copy, Default)] |
| 12 | +#[cfg_attr(feature = "datagen", derive(serde::Serialize, databake::Bake))] |
| 13 | +#[cfg_attr(feature = "datagen", databake(path = icu_properties::bidi))] |
| 14 | +#[cfg_attr(feature = "serde", derive(serde::Deserialize))] |
96 | 15 | #[non_exhaustive]
|
97 |
| -pub struct BidiMirroringProperties { |
98 |
| - /// Represents the Bidi_Mirroring_Glyph property value |
| 16 | +pub struct BidiMirroringGlyph { |
| 17 | + /// The mirroring glyph |
99 | 18 | pub mirroring_glyph: Option<char>,
|
100 |
| - /// Represents the Bidi_Mirrored property value |
| 19 | + /// Whether the glyph is mirrored |
101 | 20 | pub mirrored: bool,
|
| 21 | + /// The paired bracket type |
| 22 | + pub paired_bracket_type: BidiPairedBracketType, |
102 | 23 | }
|
103 | 24 |
|
104 |
| -/// The enum represents Bidi_Paired_Bracket_Type, the char represents Bidi_Paired_Bracket. |
105 |
| -/// Bidi_Paired_Bracket has a value of `None` when Bidi_Paired_Bracket_Type is `None`. |
106 |
| -#[derive(Debug, Eq, PartialEq)] |
107 |
| -#[non_exhaustive] |
108 |
| -pub enum BidiPairingProperties { |
109 |
| - /// Represents Bidi_Paired_Bracket_Type=Open, and the Bidi_Paired_Bracket value for that code point. |
110 |
| - Open(char), |
111 |
| - /// Represents Bidi_Paired_Bracket_Type=Close, and the Bidi_Paired_Bracket value for that code point. |
112 |
| - Close(char), |
113 |
| - /// Represents Bidi_Paired_Bracket_Type=None, which cooccurs with Bidi_Paired_Bracket |
114 |
| - /// being undefined for that code point. |
115 |
| - None, |
| 25 | +impl EnumeratedProperty for BidiMirroringGlyph { |
| 26 | + type DataMarker = BidiMirroringGlyphV1Marker; |
| 27 | + #[cfg(feature = "compiled_data")] |
| 28 | + const SINGLETON: &'static crate::provider::PropertyCodePointMapV1<'static, Self> = |
| 29 | + crate::provider::Baked::SINGLETON_BIDI_MIRRORING_GLYPH_V1_MARKER; |
116 | 30 | }
|
117 | 31 |
|
118 |
| -/// A borrowed wrapper around Bidi properties data, returned by |
119 |
| -/// [`BidiAuxiliaryProperties::as_borrowed()`]. More efficient to query. |
120 |
| -#[derive(Debug)] |
121 |
| -pub struct BidiAuxiliaryPropertiesBorrowed<'a> { |
122 |
| - data: &'a BidiAuxiliaryPropertiesV1<'a>, |
123 |
| -} |
| 32 | +impl crate::private::Sealed for BidiMirroringGlyph {} |
124 | 33 |
|
125 |
| -impl<'a> BidiAuxiliaryPropertiesBorrowed<'a> { |
126 |
| - // The source data coming from icuexportdata will use 0 to represent the |
127 |
| - // property value in cases for which the Bidi_Mirroring_Glyph property value |
128 |
| - // of a code point is undefined. Since Rust types can be more expressive, we |
129 |
| - // should represent these cases as None. |
130 |
| - fn convert_mirroring_glyph_data(trie_data_char: char) -> Option<char> { |
131 |
| - if trie_data_char as u32 == 0 { |
132 |
| - None |
133 |
| - } else { |
134 |
| - Some(trie_data_char) |
135 |
| - } |
136 |
| - } |
| 34 | +impl AsULE for BidiMirroringGlyph { |
| 35 | + type ULE = zerovec::ule::RawBytesULE<3>; |
137 | 36 |
|
138 |
| - /// Return a struct for the given code point representing Bidi mirroring-related |
139 |
| - /// property values. See [`BidiMirroringProperties`]. |
140 |
| - /// |
141 |
| - /// # Examples |
142 |
| - /// ``` |
143 |
| - /// use icu::properties::bidi::BidiAuxiliaryProperties; |
144 |
| - /// |
145 |
| - /// let bidi_data = BidiAuxiliaryProperties::new(); |
146 |
| - /// |
147 |
| - /// let open_paren = bidi_data.get32_mirroring_props('(' as u32); |
148 |
| - /// assert_eq!(open_paren.mirroring_glyph, Some(')')); |
149 |
| - /// assert_eq!(open_paren.mirrored, true); |
150 |
| - /// let close_paren = bidi_data.get32_mirroring_props(')' as u32); |
151 |
| - /// assert_eq!(close_paren.mirroring_glyph, Some('(')); |
152 |
| - /// assert_eq!(close_paren.mirrored, true); |
153 |
| - /// let open_angle_bracket = bidi_data.get32_mirroring_props('<' as u32); |
154 |
| - /// assert_eq!(open_angle_bracket.mirroring_glyph, Some('>')); |
155 |
| - /// assert_eq!(open_angle_bracket.mirrored, true); |
156 |
| - /// let close_angle_bracket = bidi_data.get32_mirroring_props('>' as u32); |
157 |
| - /// assert_eq!(close_angle_bracket.mirroring_glyph, Some('<')); |
158 |
| - /// assert_eq!(close_angle_bracket.mirrored, true); |
159 |
| - /// let three = bidi_data.get32_mirroring_props('3' as u32); |
160 |
| - /// assert_eq!(three.mirroring_glyph, None); |
161 |
| - /// assert_eq!(three.mirrored, false); |
162 |
| - /// ``` |
163 |
| - pub fn get32_mirroring_props(&self, code_point: u32) -> BidiMirroringProperties { |
164 |
| - let BidiAuxiliaryPropertiesV1::CodePointTrie(trie) = self.data; |
165 |
| - let bidi_aux_props = trie.get32(code_point); |
166 |
| - let mirroring_glyph_opt = |
167 |
| - Self::convert_mirroring_glyph_data(bidi_aux_props.mirroring_glyph); |
168 |
| - BidiMirroringProperties { |
169 |
| - mirroring_glyph: mirroring_glyph_opt, |
170 |
| - mirrored: bidi_aux_props.mirrored, |
171 |
| - } |
| 37 | + fn to_unaligned(self) -> Self::ULE { |
| 38 | + let [a, b, c, _] = TrieValue::to_u32(self).to_le_bytes(); |
| 39 | + RawBytesULE([a, b, c]) |
172 | 40 | }
|
173 |
| - |
174 |
| - /// Return a struct for the given code point representing Bidi bracket |
175 |
| - /// pairing-related property values. See [`BidiPairingProperties`] |
176 |
| - /// |
177 |
| - /// # Examples |
178 |
| - /// ``` |
179 |
| - /// use icu::properties::bidi::{BidiAuxiliaryProperties, BidiPairingProperties}; |
180 |
| - /// |
181 |
| - /// let bidi_data = BidiAuxiliaryProperties::new(); |
182 |
| - /// |
183 |
| - /// let open_paren = bidi_data.get32_pairing_props('(' as u32); |
184 |
| - /// assert_eq!(open_paren, BidiPairingProperties::Open(')')); |
185 |
| - /// let close_paren = bidi_data.get32_pairing_props(')' as u32); |
186 |
| - /// assert_eq!(close_paren, BidiPairingProperties::Close('(')); |
187 |
| - /// let open_angle_bracket = bidi_data.get32_pairing_props('<' as u32); |
188 |
| - /// assert_eq!(open_angle_bracket, BidiPairingProperties::None); |
189 |
| - /// let close_angle_bracket = bidi_data.get32_pairing_props('>' as u32); |
190 |
| - /// assert_eq!(close_angle_bracket, BidiPairingProperties::None); |
191 |
| - /// let three = bidi_data.get32_pairing_props('3' as u32); |
192 |
| - /// assert_eq!(three, BidiPairingProperties::None); |
193 |
| - /// ``` |
194 |
| - pub fn get32_pairing_props(&self, code_point: u32) -> BidiPairingProperties { |
195 |
| - let BidiAuxiliaryPropertiesV1::CodePointTrie(trie) = self.data; |
196 |
| - let bidi_aux_props = trie.get32(code_point); |
197 |
| - let mirroring_glyph = bidi_aux_props.mirroring_glyph; |
198 |
| - let paired_bracket_type = bidi_aux_props.paired_bracket_type; |
199 |
| - match paired_bracket_type { |
200 |
| - CheckedBidiPairedBracketType::Open => BidiPairingProperties::Open(mirroring_glyph), |
201 |
| - CheckedBidiPairedBracketType::Close => BidiPairingProperties::Close(mirroring_glyph), |
202 |
| - _ => BidiPairingProperties::None, |
203 |
| - } |
| 41 | + fn from_unaligned(unaligned: Self::ULE) -> Self { |
| 42 | + let [a, b, c] = unaligned.0; |
| 43 | + TrieValue::try_from_u32(u32::from_le_bytes([a, b, c, 0])).unwrap_or_default() |
204 | 44 | }
|
205 | 45 | }
|
206 | 46 |
|
207 |
| -impl BidiAuxiliaryPropertiesBorrowed<'static> { |
208 |
| - /// Cheaply converts a [`BidiAuxiliaryPropertiesBorrowed<'static>`] into a [`BidiAuxiliaryProperties`]. |
209 |
| - /// |
210 |
| - /// Note: Due to branching and indirection, using [`BidiAuxiliaryProperties`] might inhibit some |
211 |
| - /// compile-time optimizations that are possible with [`BidiAuxiliaryPropertiesBorrowed`]. |
212 |
| - pub const fn static_to_owned(self) -> BidiAuxiliaryProperties { |
213 |
| - BidiAuxiliaryProperties { |
214 |
| - data: DataPayload::from_static_ref(self.data), |
215 |
| - } |
216 |
| - } |
| 47 | +/// The enum represents Bidi_Paired_Bracket_Type. |
| 48 | +/// |
| 49 | +/// It does not implement [`EnumeratedProperty`], instead it can be obtained |
| 50 | +/// through the bitpacked [`BidiMirroringGlyph`] property. |
| 51 | +/// |
| 52 | +/// If you have a use case this property without also needing the [`BidiMirroringGlyph`] |
| 53 | +/// property, and need to optimize data size, please file an issue. |
| 54 | +#[derive(Debug, Eq, PartialEq, Copy, Clone, Default)] |
| 55 | +#[cfg_attr(feature = "datagen", derive(serde::Serialize, databake::Bake))] |
| 56 | +#[cfg_attr(feature = "datagen", databake(path = icu_properties::bidi))] |
| 57 | +#[cfg_attr(feature = "serde", derive(serde::Deserialize))] |
| 58 | +#[non_exhaustive] |
| 59 | +pub enum BidiPairedBracketType { |
| 60 | + /// Represents Bidi_Paired_Bracket_Type=Open. |
| 61 | + Open, |
| 62 | + /// Represents Bidi_Paired_Bracket_Type=Close. |
| 63 | + Close, |
| 64 | + /// Represents Bidi_Paired_Bracket_Type=None. |
| 65 | + #[default] |
| 66 | + None, |
217 | 67 | }
|
218 | 68 |
|
219 | 69 | /// Implements [`unicode_bidi::BidiDataSource`] on [`CodePointMapDataBorrowed<BidiClass>`](crate::CodePointMapDataBorrowed).
|
|
0 commit comments