/rust/registry/src/index.crates.io-1949cf8c6b5b557f/idna_adapter-1.2.2/src/lib.rs
Line | Count | Source |
1 | | // Copyright The rust-url developers. |
2 | | // |
3 | | // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or |
4 | | // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license |
5 | | // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your |
6 | | // option. This file may not be copied, modified, or distributed |
7 | | // except according to those terms. |
8 | | |
9 | | //! This crate abstracts over a Unicode back end for the [`idna`][1] |
10 | | //! crate. |
11 | | //! |
12 | | //! To work around the lack of [`global-features`][2] in Cargo, this |
13 | | //! crate allows the top level `Cargo.lock` to choose an alternative |
14 | | //! Unicode back end for the `idna` crate by pinning a version of this |
15 | | //! crate. |
16 | | //! |
17 | | //! See the [README of the latest version][3] for more details. |
18 | | //! |
19 | | //! [1]: https://docs.rs/crate/idna/latest |
20 | | //! [2]: https://internals.rust-lang.org/t/pre-rfc-mutually-excusive-global-features/19618 |
21 | | //! [3]: https://docs.rs/crate/idna_adapter/latest |
22 | | |
23 | | #![no_std] |
24 | | |
25 | | use icu_normalizer::uts46::Uts46MapperBorrowed; |
26 | | use icu_properties::props::GeneralCategory; |
27 | | use icu_properties::CodePointMapDataBorrowed; |
28 | | |
29 | | /// Turns a joining type into a mask for comparing with multiple type at once. |
30 | 0 | const fn joining_type_to_mask(jt: icu_properties::props::JoiningType) -> u32 { |
31 | 0 | 1u32 << jt.to_icu4c_value() |
32 | 0 | } |
33 | | |
34 | | /// Mask for checking for both left and dual joining. |
35 | | pub const LEFT_OR_DUAL_JOINING_MASK: JoiningTypeMask = JoiningTypeMask( |
36 | | joining_type_to_mask(icu_properties::props::JoiningType::LeftJoining) |
37 | | | joining_type_to_mask(icu_properties::props::JoiningType::DualJoining), |
38 | | ); |
39 | | |
40 | | /// Mask for checking for both left and dual joining. |
41 | | pub const RIGHT_OR_DUAL_JOINING_MASK: JoiningTypeMask = JoiningTypeMask( |
42 | | joining_type_to_mask(icu_properties::props::JoiningType::RightJoining) |
43 | | | joining_type_to_mask(icu_properties::props::JoiningType::DualJoining), |
44 | | ); |
45 | | |
46 | | /// Turns a bidi class into a mask for comparing with multiple classes at once. |
47 | 0 | const fn bidi_class_to_mask(bc: icu_properties::props::BidiClass) -> u32 { |
48 | 0 | 1u32 << bc.to_icu4c_value() |
49 | 0 | } |
50 | | |
51 | | /// Mask for checking if the domain is a bidi domain. |
52 | | pub const RTL_MASK: BidiClassMask = BidiClassMask( |
53 | | bidi_class_to_mask(icu_properties::props::BidiClass::RightToLeft) |
54 | | | bidi_class_to_mask(icu_properties::props::BidiClass::ArabicLetter) |
55 | | | bidi_class_to_mask(icu_properties::props::BidiClass::ArabicNumber), |
56 | | ); |
57 | | |
58 | | /// Mask for allowable bidi classes in the first character of a label |
59 | | /// (either LTR or RTL) in a bidi domain. |
60 | | pub const FIRST_BC_MASK: BidiClassMask = BidiClassMask( |
61 | | bidi_class_to_mask(icu_properties::props::BidiClass::LeftToRight) |
62 | | | bidi_class_to_mask(icu_properties::props::BidiClass::RightToLeft) |
63 | | | bidi_class_to_mask(icu_properties::props::BidiClass::ArabicLetter), |
64 | | ); |
65 | | |
66 | | // Mask for allowable bidi classes of the last (non-Non-Spacing Mark) |
67 | | // character in an LTR label in a bidi domain. |
68 | | pub const LAST_LTR_MASK: BidiClassMask = BidiClassMask( |
69 | | bidi_class_to_mask(icu_properties::props::BidiClass::LeftToRight) |
70 | | | bidi_class_to_mask(icu_properties::props::BidiClass::EuropeanNumber), |
71 | | ); |
72 | | |
73 | | // Mask for allowable bidi classes of the last (non-Non-Spacing Mark) |
74 | | // character in an RTL label in a bidi domain. |
75 | | pub const LAST_RTL_MASK: BidiClassMask = BidiClassMask( |
76 | | bidi_class_to_mask(icu_properties::props::BidiClass::RightToLeft) |
77 | | | bidi_class_to_mask(icu_properties::props::BidiClass::ArabicLetter) |
78 | | | bidi_class_to_mask(icu_properties::props::BidiClass::EuropeanNumber) |
79 | | | bidi_class_to_mask(icu_properties::props::BidiClass::ArabicNumber), |
80 | | ); |
81 | | |
82 | | // Mask for allowable bidi classes of the middle characters in an LTR label in a bidi domain. |
83 | | pub const MIDDLE_LTR_MASK: BidiClassMask = BidiClassMask( |
84 | | bidi_class_to_mask(icu_properties::props::BidiClass::LeftToRight) |
85 | | | bidi_class_to_mask(icu_properties::props::BidiClass::EuropeanNumber) |
86 | | | bidi_class_to_mask(icu_properties::props::BidiClass::EuropeanSeparator) |
87 | | | bidi_class_to_mask(icu_properties::props::BidiClass::CommonSeparator) |
88 | | | bidi_class_to_mask(icu_properties::props::BidiClass::EuropeanTerminator) |
89 | | | bidi_class_to_mask(icu_properties::props::BidiClass::OtherNeutral) |
90 | | | bidi_class_to_mask(icu_properties::props::BidiClass::BoundaryNeutral) |
91 | | | bidi_class_to_mask(icu_properties::props::BidiClass::NonspacingMark), |
92 | | ); |
93 | | |
94 | | // Mask for allowable bidi classes of the middle characters in an RTL label in a bidi domain. |
95 | | pub const MIDDLE_RTL_MASK: BidiClassMask = BidiClassMask( |
96 | | bidi_class_to_mask(icu_properties::props::BidiClass::RightToLeft) |
97 | | | bidi_class_to_mask(icu_properties::props::BidiClass::ArabicLetter) |
98 | | | bidi_class_to_mask(icu_properties::props::BidiClass::ArabicNumber) |
99 | | | bidi_class_to_mask(icu_properties::props::BidiClass::EuropeanNumber) |
100 | | | bidi_class_to_mask(icu_properties::props::BidiClass::EuropeanSeparator) |
101 | | | bidi_class_to_mask(icu_properties::props::BidiClass::CommonSeparator) |
102 | | | bidi_class_to_mask(icu_properties::props::BidiClass::EuropeanTerminator) |
103 | | | bidi_class_to_mask(icu_properties::props::BidiClass::OtherNeutral) |
104 | | | bidi_class_to_mask(icu_properties::props::BidiClass::BoundaryNeutral) |
105 | | | bidi_class_to_mask(icu_properties::props::BidiClass::NonspacingMark), |
106 | | ); |
107 | | |
108 | | /// Turns a genecal category into a mask for comparing with multiple categories at once. |
109 | 0 | const fn general_category_to_mask(gc: GeneralCategory) -> u32 { |
110 | 0 | 1 << (gc as u32) |
111 | 0 | } |
112 | | |
113 | | /// Mask for the disallowed general categories of the first character in a label. |
114 | | const MARK_MASK: u32 = general_category_to_mask(GeneralCategory::NonspacingMark) |
115 | | | general_category_to_mask(GeneralCategory::SpacingMark) |
116 | | | general_category_to_mask(GeneralCategory::EnclosingMark); |
117 | | |
118 | | /// Value for the Joining_Type Unicode property. |
119 | | #[repr(transparent)] |
120 | | #[derive(Clone, Copy)] |
121 | | pub struct JoiningType(icu_properties::props::JoiningType); |
122 | | |
123 | | impl JoiningType { |
124 | | /// Returns the corresponding `JoiningTypeMask`. |
125 | | #[inline(always)] |
126 | 0 | pub fn to_mask(self) -> JoiningTypeMask { |
127 | 0 | JoiningTypeMask(joining_type_to_mask(self.0)) |
128 | 0 | } |
129 | | |
130 | | // `true` iff this value is the Transparent value. |
131 | | #[inline(always)] |
132 | 0 | pub fn is_transparent(self) -> bool { |
133 | 0 | self.0 == icu_properties::props::JoiningType::Transparent |
134 | 0 | } |
135 | | } |
136 | | |
137 | | /// A mask representing potentially multiple `JoiningType` |
138 | | /// values. |
139 | | #[repr(transparent)] |
140 | | #[derive(Clone, Copy)] |
141 | | pub struct JoiningTypeMask(u32); |
142 | | |
143 | | impl JoiningTypeMask { |
144 | | /// `true` iff both masks have at `JoiningType` in common. |
145 | | #[inline(always)] |
146 | 0 | pub fn intersects(self, other: JoiningTypeMask) -> bool { |
147 | 0 | self.0 & other.0 != 0 |
148 | 0 | } |
149 | | } |
150 | | |
151 | | /// Value for the Bidi_Class Unicode property. |
152 | | #[repr(transparent)] |
153 | | #[derive(Clone, Copy)] |
154 | | pub struct BidiClass(icu_properties::props::BidiClass); |
155 | | |
156 | | impl BidiClass { |
157 | | /// Returns the corresponding `BidiClassMask`. |
158 | | #[inline(always)] |
159 | 0 | pub fn to_mask(self) -> BidiClassMask { |
160 | 0 | BidiClassMask(bidi_class_to_mask(self.0)) |
161 | 0 | } |
162 | | |
163 | | /// `true` iff this value is Left_To_Right |
164 | | #[inline(always)] |
165 | 0 | pub fn is_ltr(self) -> bool { |
166 | 0 | self.0 == icu_properties::props::BidiClass::LeftToRight |
167 | 0 | } |
168 | | |
169 | | /// `true` iff this value is Nonspacing_Mark |
170 | | #[inline(always)] |
171 | 0 | pub fn is_nonspacing_mark(self) -> bool { |
172 | 0 | self.0 == icu_properties::props::BidiClass::NonspacingMark |
173 | 0 | } |
174 | | |
175 | | /// `true` iff this value is European_Number |
176 | | #[inline(always)] |
177 | 0 | pub fn is_european_number(self) -> bool { |
178 | 0 | self.0 == icu_properties::props::BidiClass::EuropeanNumber |
179 | 0 | } |
180 | | |
181 | | /// `true` iff this value is Arabic_Number |
182 | | #[inline(always)] |
183 | 0 | pub fn is_arabic_number(self) -> bool { |
184 | 0 | self.0 == icu_properties::props::BidiClass::ArabicNumber |
185 | 0 | } |
186 | | } |
187 | | |
188 | | /// A mask representing potentially multiple `BidiClass` |
189 | | /// values. |
190 | | #[repr(transparent)] |
191 | | #[derive(Clone, Copy)] |
192 | | pub struct BidiClassMask(u32); |
193 | | |
194 | | impl BidiClassMask { |
195 | | /// `true` iff both masks have at `BidiClass` in common. |
196 | | #[inline(always)] |
197 | 0 | pub fn intersects(self, other: BidiClassMask) -> bool { |
198 | 0 | self.0 & other.0 != 0 |
199 | 0 | } |
200 | | } |
201 | | |
202 | | /// An adapter between a Unicode back end an the `idna` crate. |
203 | | pub struct Adapter { |
204 | | mapper: Uts46MapperBorrowed<'static>, |
205 | | general_category: CodePointMapDataBorrowed<'static, GeneralCategory>, |
206 | | bidi_class: CodePointMapDataBorrowed<'static, icu_properties::props::BidiClass>, |
207 | | joining_type: CodePointMapDataBorrowed<'static, icu_properties::props::JoiningType>, |
208 | | } |
209 | | |
210 | | #[cfg(feature = "compiled_data")] |
211 | | impl Default for Adapter { |
212 | 0 | fn default() -> Self { |
213 | 0 | Self::new() |
214 | 0 | } |
215 | | } |
216 | | |
217 | | impl Adapter { |
218 | | /// Constructor using data compiled into the binary. |
219 | | #[cfg(feature = "compiled_data")] |
220 | | #[inline(always)] |
221 | 0 | pub const fn new() -> Self { |
222 | 0 | Self { |
223 | 0 | mapper: Uts46MapperBorrowed::new(), |
224 | 0 | general_category: icu_properties::CodePointMapData::<GeneralCategory>::new(), |
225 | 0 | bidi_class: icu_properties::CodePointMapData::<icu_properties::props::BidiClass>::new(), |
226 | 0 | joining_type: |
227 | 0 | icu_properties::CodePointMapData::<icu_properties::props::JoiningType>::new(), |
228 | 0 | } |
229 | 0 | } |
230 | | |
231 | | /// `true` iff the Canonical_Combining_Class of `c` is Virama. |
232 | | #[inline(always)] |
233 | 0 | pub fn is_virama(&self, c: char) -> bool { |
234 | 0 | self.mapper.is_virama(c) |
235 | 0 | } |
236 | | |
237 | | /// `true` iff the General_Category of `c` is Mark, i.e. any of Nonspacing_Mark, |
238 | | /// Spacing_Mark, or Enclosing_Mark. |
239 | | #[inline(always)] |
240 | 0 | pub fn is_mark(&self, c: char) -> bool { |
241 | 0 | (general_category_to_mask(self.general_category.get(c)) & MARK_MASK) != 0 |
242 | 0 | } |
243 | | |
244 | | /// Returns the Bidi_Class of `c`. |
245 | | #[inline(always)] |
246 | 0 | pub fn bidi_class(&self, c: char) -> BidiClass { |
247 | 0 | BidiClass(self.bidi_class.get(c)) |
248 | 0 | } |
249 | | |
250 | | /// Returns the Joining_Type of `c`. |
251 | | #[inline(always)] |
252 | 0 | pub fn joining_type(&self, c: char) -> JoiningType { |
253 | 0 | JoiningType(self.joining_type.get(c)) |
254 | 0 | } |
255 | | |
256 | | /// See the [method of the same name in `icu_normalizer`][1] for the |
257 | | /// exact semantics. |
258 | | /// |
259 | | /// [1]: https://docs.rs/icu_normalizer/latest/icu_normalizer/uts46/struct.Uts46Mapper.html#method.map_normalize |
260 | | #[inline(always)] |
261 | 0 | pub fn map_normalize<'delegate, I: Iterator<Item = char> + 'delegate>( |
262 | 0 | &'delegate self, |
263 | 0 | iter: I, |
264 | 0 | ) -> impl Iterator<Item = char> + 'delegate { |
265 | 0 | self.mapper.map_normalize(iter) |
266 | 0 | } Unexecuted instantiation: <idna_adapter::Adapter>::map_normalize::<utf8_iter::Utf8Chars> Unexecuted instantiation: <idna_adapter::Adapter>::map_normalize::<_> |
267 | | |
268 | | /// See the [method of the same name in `icu_normalizer`][1] for the |
269 | | /// exact semantics. |
270 | | /// |
271 | | /// [1]: https://docs.rs/icu_normalizer/latest/icu_normalizer/uts46/struct.Uts46Mapper.html#method.normalize_validate |
272 | | #[inline(always)] |
273 | 0 | pub fn normalize_validate<'delegate, I: Iterator<Item = char> + 'delegate>( |
274 | 0 | &'delegate self, |
275 | 0 | iter: I, |
276 | 0 | ) -> impl Iterator<Item = char> + 'delegate { |
277 | 0 | self.mapper.normalize_validate(iter) |
278 | 0 | } Unexecuted instantiation: <idna_adapter::Adapter>::normalize_validate::<core::iter::adapters::copied::Copied<core::slice::iter::Iter<char>>> Unexecuted instantiation: <idna_adapter::Adapter>::normalize_validate::<_> |
279 | | } |