/rust/registry/src/index.crates.io-1949cf8c6b5b557f/icu_properties-2.1.2/src/bidi.rs
Line | Count | Source |
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 crate::{props::EnumeratedProperty, provider::PropertyEnumBidiMirroringGlyphV1}; |
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::props))] |
14 | | #[cfg_attr(feature = "serde", derive(serde::Deserialize))] |
15 | | #[allow(clippy::exhaustive_structs)] // needed for baked construction |
16 | | pub struct BidiMirroringGlyph { |
17 | | /// The mirroring glyph |
18 | | pub mirroring_glyph: Option<char>, |
19 | | /// Whether the glyph is mirrored |
20 | | pub mirrored: bool, |
21 | | /// The paired bracket type |
22 | | pub paired_bracket_type: BidiPairedBracketType, |
23 | | } |
24 | | |
25 | | impl EnumeratedProperty for BidiMirroringGlyph { |
26 | | type DataMarker = PropertyEnumBidiMirroringGlyphV1; |
27 | | #[cfg(feature = "compiled_data")] |
28 | | const SINGLETON: &'static crate::provider::PropertyCodePointMap<'static, Self> = |
29 | | crate::provider::Baked::SINGLETON_PROPERTY_ENUM_BIDI_MIRRORING_GLYPH_V1; |
30 | | const NAME: &'static [u8] = b"Bidi_Mirroring_Glyph"; |
31 | | const SHORT_NAME: &'static [u8] = b"bmg"; |
32 | | } |
33 | | |
34 | | impl crate::private::Sealed for BidiMirroringGlyph {} |
35 | | |
36 | | impl AsULE for BidiMirroringGlyph { |
37 | | type ULE = zerovec::ule::RawBytesULE<3>; |
38 | | |
39 | 0 | fn to_unaligned(self) -> Self::ULE { |
40 | 0 | let [a, b, c, _] = TrieValue::to_u32(self).to_le_bytes(); |
41 | 0 | RawBytesULE([a, b, c]) |
42 | 0 | } |
43 | 0 | fn from_unaligned(unaligned: Self::ULE) -> Self { |
44 | 0 | let [a, b, c] = unaligned.0; |
45 | 0 | TrieValue::try_from_u32(u32::from_le_bytes([a, b, c, 0])).unwrap_or_default() |
46 | 0 | } |
47 | | } |
48 | | |
49 | | /// The enum represents Bidi_Paired_Bracket_Type. |
50 | | /// |
51 | | /// It does not implement [`EnumeratedProperty`], instead it can be obtained |
52 | | /// through the bitpacked [`BidiMirroringGlyph`] property. |
53 | | /// |
54 | | /// If you have a use case this property without also needing the [`BidiMirroringGlyph`] |
55 | | /// property, and need to optimize data size, please file an issue. |
56 | | #[derive(Debug, Eq, PartialEq, Copy, Clone, Default)] |
57 | | #[cfg_attr(feature = "datagen", derive(serde::Serialize, databake::Bake))] |
58 | | #[cfg_attr(feature = "datagen", databake(path = icu_properties::props))] |
59 | | #[cfg_attr(feature = "serde", derive(serde::Deserialize))] |
60 | | #[non_exhaustive] |
61 | | pub enum BidiPairedBracketType { |
62 | | /// Represents Bidi_Paired_Bracket_Type=Open. |
63 | | Open, |
64 | | /// Represents Bidi_Paired_Bracket_Type=Close. |
65 | | Close, |
66 | | /// Represents Bidi_Paired_Bracket_Type=None. |
67 | | #[default] |
68 | | None, |
69 | | } |
70 | | |
71 | | #[cfg(feature = "unicode_bidi")] |
72 | | use crate::props::BidiClass; |
73 | | |
74 | | /// ✨ *Enabled with the `unicode_bidi` Cargo feature.* |
75 | | /// |
76 | | /// # Examples |
77 | | /// |
78 | | ///``` |
79 | | /// use icu::properties::CodePointMapData; |
80 | | /// use icu::properties::props::BidiClass; |
81 | | /// use unicode_bidi::BidiInfo; |
82 | | /// |
83 | | /// // This example text is defined using `concat!` because some browsers |
84 | | /// // and text editors have trouble displaying bidi strings. |
85 | | /// let text = concat!["א", // RTL#1 |
86 | | /// "ב", // RTL#2 |
87 | | /// "ג", // RTL#3 |
88 | | /// "a", // LTR#1 |
89 | | /// "b", // LTR#2 |
90 | | /// "c", // LTR#3 |
91 | | /// ]; // |
92 | | /// |
93 | | /// |
94 | | /// let bidi_map = CodePointMapData::<BidiClass>::new(); |
95 | | /// |
96 | | /// // Resolve embedding levels within the text. Pass `None` to detect the |
97 | | /// // paragraph level automatically. |
98 | | /// let bidi_info = BidiInfo::new_with_data_source(&bidi_map, text, None); |
99 | | /// |
100 | | /// // This paragraph has embedding level 1 because its first strong character is RTL. |
101 | | /// assert_eq!(bidi_info.paragraphs.len(), 1); |
102 | | /// let para = &bidi_info.paragraphs[0]; |
103 | | /// assert_eq!(para.level.number(), 1); |
104 | | /// assert!(para.level.is_rtl()); |
105 | | /// |
106 | | /// // Re-ordering is done after wrapping each paragraph into a sequence of |
107 | | /// // lines. For this example, I'll just use a single line that spans the |
108 | | /// // entire paragraph. |
109 | | /// let line = para.range.clone(); |
110 | | /// |
111 | | /// let display = bidi_info.reorder_line(para, line); |
112 | | /// assert_eq!(display, concat!["a", // LTR#1 |
113 | | /// "b", // LTR#2 |
114 | | /// "c", // LTR#3 |
115 | | /// "ג", // RTL#3 |
116 | | /// "ב", // RTL#2 |
117 | | /// "א", // RTL#1 |
118 | | /// ]); |
119 | | /// ``` |
120 | | #[cfg(feature = "unicode_bidi")] |
121 | | impl unicode_bidi::data_source::BidiDataSource for crate::CodePointMapDataBorrowed<'_, BidiClass> { |
122 | | fn bidi_class(&self, c: char) -> unicode_bidi::BidiClass { |
123 | | self.get(c).into() |
124 | | } |
125 | | } |
126 | | |
127 | | #[cfg(feature = "unicode_bidi")] |
128 | | impl From<BidiClass> for unicode_bidi::BidiClass { |
129 | | fn from(value: BidiClass) -> Self { |
130 | | match value { |
131 | | BidiClass::LeftToRight => unicode_bidi::BidiClass::L, |
132 | | BidiClass::RightToLeft => unicode_bidi::BidiClass::R, |
133 | | BidiClass::EuropeanNumber => unicode_bidi::BidiClass::EN, |
134 | | BidiClass::EuropeanSeparator => unicode_bidi::BidiClass::ES, |
135 | | BidiClass::EuropeanTerminator => unicode_bidi::BidiClass::ET, |
136 | | BidiClass::ArabicNumber => unicode_bidi::BidiClass::AN, |
137 | | BidiClass::CommonSeparator => unicode_bidi::BidiClass::CS, |
138 | | BidiClass::ParagraphSeparator => unicode_bidi::BidiClass::B, |
139 | | BidiClass::SegmentSeparator => unicode_bidi::BidiClass::S, |
140 | | BidiClass::WhiteSpace => unicode_bidi::BidiClass::WS, |
141 | | BidiClass::OtherNeutral => unicode_bidi::BidiClass::ON, |
142 | | BidiClass::LeftToRightEmbedding => unicode_bidi::BidiClass::LRE, |
143 | | BidiClass::LeftToRightOverride => unicode_bidi::BidiClass::LRO, |
144 | | BidiClass::ArabicLetter => unicode_bidi::BidiClass::AL, |
145 | | BidiClass::RightToLeftEmbedding => unicode_bidi::BidiClass::RLE, |
146 | | BidiClass::RightToLeftOverride => unicode_bidi::BidiClass::RLO, |
147 | | BidiClass::PopDirectionalFormat => unicode_bidi::BidiClass::PDF, |
148 | | BidiClass::NonspacingMark => unicode_bidi::BidiClass::NSM, |
149 | | BidiClass::BoundaryNeutral => unicode_bidi::BidiClass::BN, |
150 | | BidiClass::FirstStrongIsolate => unicode_bidi::BidiClass::FSI, |
151 | | BidiClass::LeftToRightIsolate => unicode_bidi::BidiClass::LRI, |
152 | | BidiClass::RightToLeftIsolate => unicode_bidi::BidiClass::RLI, |
153 | | BidiClass::PopDirectionalIsolate => unicode_bidi::BidiClass::PDI, |
154 | | // This must not happen. |
155 | | _ => unicode_bidi::BidiClass::ON, |
156 | | } |
157 | | } |
158 | | } |
159 | | |
160 | | #[cfg(feature = "unicode_bidi")] |
161 | | impl From<unicode_bidi::BidiClass> for BidiClass { |
162 | | fn from(value: unicode_bidi::BidiClass) -> Self { |
163 | | match value { |
164 | | unicode_bidi::BidiClass::L => BidiClass::LeftToRight, |
165 | | unicode_bidi::BidiClass::R => BidiClass::RightToLeft, |
166 | | unicode_bidi::BidiClass::EN => BidiClass::EuropeanNumber, |
167 | | unicode_bidi::BidiClass::ES => BidiClass::EuropeanSeparator, |
168 | | unicode_bidi::BidiClass::ET => BidiClass::EuropeanTerminator, |
169 | | unicode_bidi::BidiClass::AN => BidiClass::ArabicNumber, |
170 | | unicode_bidi::BidiClass::CS => BidiClass::CommonSeparator, |
171 | | unicode_bidi::BidiClass::B => BidiClass::ParagraphSeparator, |
172 | | unicode_bidi::BidiClass::S => BidiClass::SegmentSeparator, |
173 | | unicode_bidi::BidiClass::WS => BidiClass::WhiteSpace, |
174 | | unicode_bidi::BidiClass::ON => BidiClass::OtherNeutral, |
175 | | unicode_bidi::BidiClass::LRE => BidiClass::LeftToRightEmbedding, |
176 | | unicode_bidi::BidiClass::LRO => BidiClass::LeftToRightOverride, |
177 | | unicode_bidi::BidiClass::AL => BidiClass::ArabicLetter, |
178 | | unicode_bidi::BidiClass::RLE => BidiClass::RightToLeftEmbedding, |
179 | | unicode_bidi::BidiClass::RLO => BidiClass::RightToLeftOverride, |
180 | | unicode_bidi::BidiClass::PDF => BidiClass::PopDirectionalFormat, |
181 | | unicode_bidi::BidiClass::NSM => BidiClass::NonspacingMark, |
182 | | unicode_bidi::BidiClass::BN => BidiClass::BoundaryNeutral, |
183 | | unicode_bidi::BidiClass::FSI => BidiClass::FirstStrongIsolate, |
184 | | unicode_bidi::BidiClass::LRI => BidiClass::LeftToRightIsolate, |
185 | | unicode_bidi::BidiClass::RLI => BidiClass::RightToLeftIsolate, |
186 | | unicode_bidi::BidiClass::PDI => BidiClass::PopDirectionalIsolate, |
187 | | } |
188 | | } |
189 | | } |