1use alloc::{
17 string::{String, ToString},
18 vec::Vec,
19};
20use core::slice;
21
22use super::char_data::BidiClass;
23
24#[derive(Copy, Clone, Debug, Eq, Ord, PartialEq, PartialOrd)]
35#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
36#[repr(transparent)]
37pub struct Level(u8);
38
39pub const LTR_LEVEL: Level = Level(0);
40pub const RTL_LEVEL: Level = Level(1);
41
42const MAX_DEPTH: u8 = 125;
43pub const MAX_EXPLICIT_DEPTH: u8 = MAX_DEPTH;
45pub const MAX_IMPLICIT_DEPTH: u8 = MAX_DEPTH + 1;
47
48#[derive(Debug, PartialEq)]
50pub enum Error {
51 OutOfRangeNumber,
53}
54
55impl Level {
56 #[inline]
58 pub fn ltr() -> Level {
59 LTR_LEVEL
60 }
61
62 #[inline]
64 pub fn rtl() -> Level {
65 RTL_LEVEL
66 }
67
68 pub fn max_implicit_depth() -> u8 {
70 MAX_IMPLICIT_DEPTH
71 }
72
73 pub fn max_explicit_depth() -> u8 {
75 MAX_EXPLICIT_DEPTH
76 }
77
78 #[inline]
82 pub fn new(number: u8) -> Result<Level, Error> {
83 if number <= MAX_IMPLICIT_DEPTH {
84 Ok(Level(number))
85 } else {
86 Err(Error::OutOfRangeNumber)
87 }
88 }
89
90 #[inline]
92 pub fn new_explicit(number: u8) -> Result<Level, Error> {
93 if number <= MAX_EXPLICIT_DEPTH {
94 Ok(Level(number))
95 } else {
96 Err(Error::OutOfRangeNumber)
97 }
98 }
99
100 #[inline]
104 pub fn number(&self) -> u8 {
105 self.0
106 }
107
108 #[inline]
110 pub fn is_ltr(&self) -> bool {
111 self.0 % 2 == 0
112 }
113
114 #[inline]
116 pub fn is_rtl(&self) -> bool {
117 self.0 % 2 == 1
118 }
119
120 #[inline]
124 pub fn raise(&mut self, amount: u8) -> Result<(), Error> {
125 match self.0.checked_add(amount) {
126 Some(number) => {
127 if number <= MAX_IMPLICIT_DEPTH {
128 self.0 = number;
129 Ok(())
130 } else {
131 Err(Error::OutOfRangeNumber)
132 }
133 }
134 None => Err(Error::OutOfRangeNumber),
135 }
136 }
137
138 #[inline]
140 pub fn raise_explicit(&mut self, amount: u8) -> Result<(), Error> {
141 match self.0.checked_add(amount) {
142 Some(number) => {
143 if number <= MAX_EXPLICIT_DEPTH {
144 self.0 = number;
145 Ok(())
146 } else {
147 Err(Error::OutOfRangeNumber)
148 }
149 }
150 None => Err(Error::OutOfRangeNumber),
151 }
152 }
153
154 #[inline]
156 pub fn lower(&mut self, amount: u8) -> Result<(), Error> {
157 match self.0.checked_sub(amount) {
158 Some(number) => {
159 self.0 = number;
160 Ok(())
161 }
162 None => Err(Error::OutOfRangeNumber),
163 }
164 }
165
166 #[inline]
170 pub fn new_explicit_next_ltr(&self) -> Result<Level, Error> {
171 Level::new_explicit((self.0 + 2) & !1)
172 }
173
174 #[inline]
176 pub fn new_explicit_next_rtl(&self) -> Result<Level, Error> {
177 Level::new_explicit((self.0 + 1) | 1)
178 }
179
180 #[inline]
183 pub fn new_lowest_ge_rtl(&self) -> Result<Level, Error> {
184 Level::new(self.0 | 1)
185 }
186
187 #[inline]
189 pub fn bidi_class(&self) -> BidiClass {
190 if self.is_rtl() {
191 BidiClass::R
192 } else {
193 BidiClass::L
194 }
195 }
196
197 pub fn vec(v: &[u8]) -> Vec<Level> {
198 v.iter().map(|&x| x.into()).collect()
199 }
200
201 pub fn from_slice_unchecked(v: &[u8]) -> &[Level] {
206 debug_assert_eq!(core::mem::size_of::<u8>(), core::mem::size_of::<Level>());
207 unsafe {
208 slice::from_raw_parts(v as *const [u8] as *const u8 as *const Level, v.len())
211 }
212 }
213}
214
215#[inline]
219pub fn has_rtl(levels: &[Level]) -> bool {
220 levels.iter().any(|&lvl| lvl.is_rtl())
221}
222
223impl From<Level> for u8 {
224 #[inline]
226 fn from(val: Level) -> Self {
227 val.number()
228 }
229}
230
231impl From<u8> for Level {
232 #[inline]
234 fn from(number: u8) -> Level {
235 Level::new(number).expect("Level number error")
236 }
237}
238
239impl<'a> PartialEq<&'a str> for Level {
241 #[inline]
242 fn eq(&self, s: &&'a str) -> bool {
243 *s == "x" || *s == self.0.to_string()
244 }
245}
246
247impl PartialEq<String> for Level {
249 #[inline]
250 fn eq(&self, s: &String) -> bool {
251 self == &s.as_str()
252 }
253}
254
255#[cfg(test)]
256mod tests {
257 use super::*;
258
259 #[test]
260 fn test_new() {
261 assert_eq!(Level::new(0), Ok(Level(0)));
262 assert_eq!(Level::new(1), Ok(Level(1)));
263 assert_eq!(Level::new(10), Ok(Level(10)));
264 assert_eq!(Level::new(125), Ok(Level(125)));
265 assert_eq!(Level::new(126), Ok(Level(126)));
266 assert_eq!(Level::new(127), Err(Error::OutOfRangeNumber));
267 assert_eq!(Level::new(255), Err(Error::OutOfRangeNumber));
268 }
269
270 #[test]
271 fn test_new_explicit() {
272 assert_eq!(Level::new_explicit(0), Ok(Level(0)));
273 assert_eq!(Level::new_explicit(1), Ok(Level(1)));
274 assert_eq!(Level::new_explicit(10), Ok(Level(10)));
275 assert_eq!(Level::new_explicit(125), Ok(Level(125)));
276 assert_eq!(Level::new_explicit(126), Err(Error::OutOfRangeNumber));
277 assert_eq!(Level::new_explicit(255), Err(Error::OutOfRangeNumber));
278 }
279
280 #[test]
281 fn test_is_ltr() {
282 assert_eq!(Level(0).is_ltr(), true);
283 assert_eq!(Level(1).is_ltr(), false);
284 assert_eq!(Level(10).is_ltr(), true);
285 assert_eq!(Level(11).is_ltr(), false);
286 assert_eq!(Level(124).is_ltr(), true);
287 assert_eq!(Level(125).is_ltr(), false);
288 }
289
290 #[test]
291 fn test_is_rtl() {
292 assert_eq!(Level(0).is_rtl(), false);
293 assert_eq!(Level(1).is_rtl(), true);
294 assert_eq!(Level(10).is_rtl(), false);
295 assert_eq!(Level(11).is_rtl(), true);
296 assert_eq!(Level(124).is_rtl(), false);
297 assert_eq!(Level(125).is_rtl(), true);
298 }
299
300 #[test]
301 fn test_raise() {
302 let mut level = Level::ltr();
303 assert_eq!(level.number(), 0);
304 assert!(level.raise(100).is_ok());
305 assert_eq!(level.number(), 100);
306 assert!(level.raise(26).is_ok());
307 assert_eq!(level.number(), 126);
308 assert!(level.raise(1).is_err()); assert!(level.raise(250).is_err()); assert_eq!(level.number(), 126);
311 }
312
313 #[test]
314 fn test_raise_explicit() {
315 let mut level = Level::ltr();
316 assert_eq!(level.number(), 0);
317 assert!(level.raise_explicit(100).is_ok());
318 assert_eq!(level.number(), 100);
319 assert!(level.raise_explicit(25).is_ok());
320 assert_eq!(level.number(), 125);
321 assert!(level.raise_explicit(1).is_err()); assert!(level.raise_explicit(250).is_err()); assert_eq!(level.number(), 125);
324 }
325
326 #[test]
327 fn test_lower() {
328 let mut level = Level::rtl();
329 assert_eq!(level.number(), 1);
330 assert!(level.lower(1).is_ok());
331 assert_eq!(level.number(), 0);
332 assert!(level.lower(1).is_err()); assert!(level.lower(250).is_err()); assert_eq!(level.number(), 0);
335 }
336
337 #[test]
338 fn test_has_rtl() {
339 assert_eq!(has_rtl(&Level::vec(&[0, 0, 0])), false);
340 assert_eq!(has_rtl(&Level::vec(&[0, 1, 0])), true);
341 assert_eq!(has_rtl(&Level::vec(&[0, 2, 0])), false);
342 assert_eq!(has_rtl(&Level::vec(&[0, 125, 0])), true);
343 assert_eq!(has_rtl(&Level::vec(&[0, 126, 0])), false);
344 }
345
346 #[test]
347 fn test_into() {
348 let level = Level::rtl();
349 let number: u8 = level.into();
350 assert_eq!(1u8, number);
351 }
352
353 #[test]
354 fn test_vec() {
355 assert_eq!(
356 Level::vec(&[0, 1, 125]),
357 vec![Level(0), Level(1), Level(125)]
358 );
359 }
360
361 #[test]
362 fn test_str_eq() {
363 assert_eq!(Level::vec(&[0, 1, 4, 125]), vec!["0", "1", "x", "125"]);
364 assert_ne!(Level::vec(&[0, 1, 4, 125]), vec!["0", "1", "5", "125"]);
365 }
366
367 #[test]
368 fn test_string_eq() {
369 assert_eq!(
370 Level::vec(&[0, 1, 4, 125]),
371 vec!["0".to_string(), "1".to_string(), "x".to_string(), "125".to_string()]
372 );
373 }
374}
375
376#[cfg(all(feature = "serde", test))]
377mod serde_tests {
378 use super::*;
379 use serde_test::{assert_tokens, Token};
380
381 #[test]
382 fn test_statics() {
383 assert_tokens(
384 &Level::ltr(),
385 &[Token::NewtypeStruct { name: "Level" }, Token::U8(0)],
386 );
387 assert_tokens(
388 &Level::rtl(),
389 &[Token::NewtypeStruct { name: "Level" }, Token::U8(1)],
390 );
391 }
392
393 #[test]
394 fn test_new() {
395 let level = Level::new(42).unwrap();
396 assert_tokens(
397 &level,
398 &[Token::NewtypeStruct { name: "Level" }, Token::U8(42)],
399 );
400 }
401}