1#![no_std]
24
25use unicode_normalization::UnicodeNormalization;
26
27pub const LEFT_OR_DUAL_JOINING_MASK: JoiningTypeMask =
29 JoiningTypeMask(idna_mapping::LEFT_OR_DUAL_JOINING_MASK);
30
31pub const RIGHT_OR_DUAL_JOINING_MASK: JoiningTypeMask =
33 JoiningTypeMask(idna_mapping::RIGHT_OR_DUAL_JOINING_MASK);
34
35const fn bidi_class_to_mask(bc: unicode_bidi::BidiClass) -> u32 {
37 1u32 << (bc as u32)
38}
39
40pub const RTL_MASK: BidiClassMask = BidiClassMask(
42 bidi_class_to_mask(unicode_bidi::BidiClass::R)
43 | bidi_class_to_mask(unicode_bidi::BidiClass::AL)
44 | bidi_class_to_mask(unicode_bidi::BidiClass::AN),
45);
46
47pub const FIRST_BC_MASK: BidiClassMask = BidiClassMask(
50 bidi_class_to_mask(unicode_bidi::BidiClass::L)
51 | bidi_class_to_mask(unicode_bidi::BidiClass::R)
52 | bidi_class_to_mask(unicode_bidi::BidiClass::AL),
53);
54
55pub const LAST_LTR_MASK: BidiClassMask = BidiClassMask(
58 bidi_class_to_mask(unicode_bidi::BidiClass::L)
59 | bidi_class_to_mask(unicode_bidi::BidiClass::EN),
60);
61
62pub const LAST_RTL_MASK: BidiClassMask = BidiClassMask(
65 bidi_class_to_mask(unicode_bidi::BidiClass::R)
66 | bidi_class_to_mask(unicode_bidi::BidiClass::AL)
67 | bidi_class_to_mask(unicode_bidi::BidiClass::EN)
68 | bidi_class_to_mask(unicode_bidi::BidiClass::AN),
69);
70
71pub const MIDDLE_LTR_MASK: BidiClassMask = BidiClassMask(
73 bidi_class_to_mask(unicode_bidi::BidiClass::L)
74 | bidi_class_to_mask(unicode_bidi::BidiClass::EN)
75 | bidi_class_to_mask(unicode_bidi::BidiClass::ES)
76 | bidi_class_to_mask(unicode_bidi::BidiClass::CS)
77 | bidi_class_to_mask(unicode_bidi::BidiClass::ET)
78 | bidi_class_to_mask(unicode_bidi::BidiClass::ON)
79 | bidi_class_to_mask(unicode_bidi::BidiClass::BN)
80 | bidi_class_to_mask(unicode_bidi::BidiClass::NSM),
81);
82
83pub const MIDDLE_RTL_MASK: BidiClassMask = BidiClassMask(
85 bidi_class_to_mask(unicode_bidi::BidiClass::R)
86 | bidi_class_to_mask(unicode_bidi::BidiClass::AL)
87 | bidi_class_to_mask(unicode_bidi::BidiClass::AN)
88 | bidi_class_to_mask(unicode_bidi::BidiClass::EN)
89 | bidi_class_to_mask(unicode_bidi::BidiClass::ES)
90 | bidi_class_to_mask(unicode_bidi::BidiClass::CS)
91 | bidi_class_to_mask(unicode_bidi::BidiClass::ET)
92 | bidi_class_to_mask(unicode_bidi::BidiClass::ON)
93 | bidi_class_to_mask(unicode_bidi::BidiClass::BN)
94 | bidi_class_to_mask(unicode_bidi::BidiClass::NSM),
95);
96
97#[repr(transparent)]
99#[derive(Clone, Copy)]
100pub struct JoiningType(idna_mapping::JoiningType);
101
102impl JoiningType {
103 #[inline(always)]
105 pub fn to_mask(self) -> JoiningTypeMask {
106 JoiningTypeMask(self.0.to_mask())
107 }
108
109 #[inline(always)]
111 pub fn is_transparent(self) -> bool {
112 self.0.is_transparent()
113 }
114}
115
116#[repr(transparent)]
119#[derive(Clone, Copy)]
120pub struct JoiningTypeMask(idna_mapping::JoiningTypeMask);
121
122impl JoiningTypeMask {
123 #[inline(always)]
125 pub fn intersects(self, other: JoiningTypeMask) -> bool {
126 self.0.intersects(other.0)
127 }
128}
129
130#[repr(transparent)]
132#[derive(Clone, Copy)]
133pub struct BidiClass(unicode_bidi::BidiClass);
134
135impl BidiClass {
136 #[inline(always)]
138 pub fn to_mask(self) -> BidiClassMask {
139 BidiClassMask(bidi_class_to_mask(self.0))
140 }
141
142 #[inline(always)]
144 pub fn is_ltr(self) -> bool {
145 self.0 == unicode_bidi::BidiClass::L
146 }
147
148 #[inline(always)]
150 pub fn is_nonspacing_mark(self) -> bool {
151 self.0 == unicode_bidi::BidiClass::NSM
152 }
153
154 #[inline(always)]
156 pub fn is_european_number(self) -> bool {
157 self.0 == unicode_bidi::BidiClass::EN
158 }
159
160 #[inline(always)]
162 pub fn is_arabic_number(self) -> bool {
163 self.0 == unicode_bidi::BidiClass::AN
164 }
165}
166
167#[repr(transparent)]
170#[derive(Clone, Copy)]
171pub struct BidiClassMask(u32);
172
173impl BidiClassMask {
174 #[inline(always)]
176 pub fn intersects(self, other: BidiClassMask) -> bool {
177 self.0 & other.0 != 0
178 }
179}
180
181#[non_exhaustive]
183pub struct Adapter {}
184
185#[cfg(feature = "compiled_data")]
186impl Default for Adapter {
187 fn default() -> Self {
188 Self::new()
189 }
190}
191
192impl Adapter {
193 #[cfg(feature = "compiled_data")]
195 #[inline(always)]
196 pub const fn new() -> Self {
197 Self {}
198 }
199
200 #[inline(always)]
202 pub fn is_virama(&self, c: char) -> bool {
203 unicode_normalization::char::canonical_combining_class(c) == 9
204 }
205
206 #[inline(always)]
209 pub fn is_mark(&self, c: char) -> bool {
210 unicode_normalization::char::is_combining_mark(c)
211 }
212
213 #[inline(always)]
215 pub fn bidi_class(&self, c: char) -> BidiClass {
216 BidiClass(unicode_bidi::bidi_class(c))
217 }
218
219 #[inline(always)]
221 pub fn joining_type(&self, c: char) -> JoiningType {
222 JoiningType(idna_mapping::joining_type(c))
223 }
224
225 #[inline(always)]
230 pub fn map_normalize<'delegate, I: Iterator<Item = char> + 'delegate>(
231 &'delegate self,
232 iter: I,
233 ) -> impl Iterator<Item = char> + 'delegate {
234 idna_mapping::Mapper::new(iter, false).nfc()
235 }
236
237 #[inline(always)]
242 pub fn normalize_validate<'delegate, I: Iterator<Item = char> + 'delegate>(
243 &'delegate self,
244 iter: I,
245 ) -> impl Iterator<Item = char> + 'delegate {
246 idna_mapping::Mapper::new(iter, true).nfc()
247 }
248}