1use std::convert::{From, Into};
17
18use super::char_data::BidiClass;
19
20#[derive(Copy, Clone, Debug, Eq, Ord, PartialEq, PartialOrd)]
31#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
32pub struct Level(u8);
33
34pub const LTR_LEVEL: Level = Level(0);
35pub const RTL_LEVEL: Level = Level(1);
36
37const MAX_DEPTH: u8 = 125;
38pub const MAX_EXPLICIT_DEPTH: u8 = MAX_DEPTH;
40pub const MAX_IMPLICIT_DEPTH: u8 = MAX_DEPTH + 1;
42
43#[derive(Debug, PartialEq)]
45pub enum Error {
46 OutOfRangeNumber,
48}
49
50impl Level {
51 #[inline]
53 pub fn ltr() -> Level {
54 LTR_LEVEL
55 }
56
57 #[inline]
59 pub fn rtl() -> Level {
60 RTL_LEVEL
61 }
62
63 pub fn max_implicit_depth() -> u8 {
65 MAX_IMPLICIT_DEPTH
66 }
67
68 pub fn max_explicit_depth() -> u8 {
70 MAX_EXPLICIT_DEPTH
71 }
72
73 #[inline]
77 pub fn new(number: u8) -> Result<Level, Error> {
78 if number <= MAX_IMPLICIT_DEPTH {
79 Ok(Level(number))
80 } else {
81 Err(Error::OutOfRangeNumber)
82 }
83 }
84
85 #[inline]
87 pub fn new_explicit(number: u8) -> Result<Level, Error> {
88 if number <= MAX_EXPLICIT_DEPTH {
89 Ok(Level(number))
90 } else {
91 Err(Error::OutOfRangeNumber)
92 }
93 }
94
95 #[inline]
99 pub fn number(&self) -> u8 {
100 self.0
101 }
102
103 #[inline]
105 pub fn is_ltr(&self) -> bool {
106 self.0 % 2 == 0
107 }
108
109 #[inline]
111 pub fn is_rtl(&self) -> bool {
112 self.0 % 2 == 1
113 }
114
115 #[inline]
119 pub fn raise(&mut self, amount: u8) -> Result<(), Error> {
120 match self.0.checked_add(amount) {
121 Some(number) => {
122 if number <= MAX_IMPLICIT_DEPTH {
123 self.0 = number;
124 Ok(())
125 } else {
126 Err(Error::OutOfRangeNumber)
127 }
128 }
129 None => Err(Error::OutOfRangeNumber),
130 }
131 }
132
133 #[inline]
135 pub fn raise_explicit(&mut self, amount: u8) -> Result<(), Error> {
136 match self.0.checked_add(amount) {
137 Some(number) => {
138 if number <= MAX_EXPLICIT_DEPTH {
139 self.0 = number;
140 Ok(())
141 } else {
142 Err(Error::OutOfRangeNumber)
143 }
144 }
145 None => Err(Error::OutOfRangeNumber),
146 }
147 }
148
149 #[inline]
151 pub fn lower(&mut self, amount: u8) -> Result<(), Error> {
152 match self.0.checked_sub(amount) {
153 Some(number) => {
154 self.0 = number;
155 Ok(())
156 }
157 None => Err(Error::OutOfRangeNumber),
158 }
159 }
160
161 #[inline]
165 pub fn new_explicit_next_ltr(&self) -> Result<Level, Error> {
166 Level::new_explicit((self.0 + 2) & !1)
167 }
168
169 #[inline]
171 pub fn new_explicit_next_rtl(&self) -> Result<Level, Error> {
172 Level::new_explicit((self.0 + 1) | 1)
173 }
174
175 #[inline]
178 pub fn new_lowest_ge_rtl(&self) -> Result<Level, Error> {
179 Level::new(self.0 | 1)
180 }
181
182 #[inline]
184 pub fn bidi_class(&self) -> BidiClass {
185 if self.is_rtl() {
186 BidiClass::R
187 } else {
188 BidiClass::L
189 }
190 }
191
192 pub fn vec(v: &[u8]) -> Vec<Level> {
193 v.iter().map(|&x| x.into()).collect()
194 }
195}
196
197#[inline]
201pub fn has_rtl(levels: &[Level]) -> bool {
202 levels.iter().any(|&lvl| lvl.is_rtl())
203}
204
205impl Into<u8> for Level {
206 #[inline]
208 fn into(self) -> u8 {
209 self.number()
210 }
211}
212
213impl From<u8> for Level {
214 #[inline]
216 fn from(number: u8) -> Level {
217 Level::new(number).expect("Level number error")
218 }
219}
220
221impl<'a> PartialEq<&'a str> for Level {
223 #[inline]
224 fn eq(&self, s: &&'a str) -> bool {
225 *s == "x" || *s == self.0.to_string()
226 }
227}
228
229impl<'a> PartialEq<String> for Level {
231 #[inline]
232 fn eq(&self, s: &String) -> bool {
233 self == &s.as_str()
234 }
235}
236
237#[cfg(test)]
238mod tests {
239 use super::*;
240
241 #[test]
242 fn test_new() {
243 assert_eq!(Level::new(0), Ok(Level(0)));
244 assert_eq!(Level::new(1), Ok(Level(1)));
245 assert_eq!(Level::new(10), Ok(Level(10)));
246 assert_eq!(Level::new(125), Ok(Level(125)));
247 assert_eq!(Level::new(126), Ok(Level(126)));
248 assert_eq!(Level::new(127), Err(Error::OutOfRangeNumber));
249 assert_eq!(Level::new(255), Err(Error::OutOfRangeNumber));
250 }
251
252 #[test]
253 fn test_new_explicit() {
254 assert_eq!(Level::new_explicit(0), Ok(Level(0)));
255 assert_eq!(Level::new_explicit(1), Ok(Level(1)));
256 assert_eq!(Level::new_explicit(10), Ok(Level(10)));
257 assert_eq!(Level::new_explicit(125), Ok(Level(125)));
258 assert_eq!(Level::new_explicit(126), Err(Error::OutOfRangeNumber));
259 assert_eq!(Level::new_explicit(255), Err(Error::OutOfRangeNumber));
260 }
261
262 #[test]
263 fn test_is_ltr() {
264 assert_eq!(Level(0).is_ltr(), true);
265 assert_eq!(Level(1).is_ltr(), false);
266 assert_eq!(Level(10).is_ltr(), true);
267 assert_eq!(Level(11).is_ltr(), false);
268 assert_eq!(Level(124).is_ltr(), true);
269 assert_eq!(Level(125).is_ltr(), false);
270 }
271
272 #[test]
273 fn test_is_rtl() {
274 assert_eq!(Level(0).is_rtl(), false);
275 assert_eq!(Level(1).is_rtl(), true);
276 assert_eq!(Level(10).is_rtl(), false);
277 assert_eq!(Level(11).is_rtl(), true);
278 assert_eq!(Level(124).is_rtl(), false);
279 assert_eq!(Level(125).is_rtl(), true);
280 }
281
282 #[test]
283 fn test_raise() {
284 let mut level = Level::ltr();
285 assert_eq!(level.number(), 0);
286 assert!(level.raise(100).is_ok());
287 assert_eq!(level.number(), 100);
288 assert!(level.raise(26).is_ok());
289 assert_eq!(level.number(), 126);
290 assert!(level.raise(1).is_err()); assert!(level.raise(250).is_err()); assert_eq!(level.number(), 126);
293 }
294
295 #[test]
296 fn test_raise_explicit() {
297 let mut level = Level::ltr();
298 assert_eq!(level.number(), 0);
299 assert!(level.raise_explicit(100).is_ok());
300 assert_eq!(level.number(), 100);
301 assert!(level.raise_explicit(25).is_ok());
302 assert_eq!(level.number(), 125);
303 assert!(level.raise_explicit(1).is_err()); assert!(level.raise_explicit(250).is_err()); assert_eq!(level.number(), 125);
306 }
307
308 #[test]
309 fn test_lower() {
310 let mut level = Level::rtl();
311 assert_eq!(level.number(), 1);
312 assert!(level.lower(1).is_ok());
313 assert_eq!(level.number(), 0);
314 assert!(level.lower(1).is_err()); assert!(level.lower(250).is_err()); assert_eq!(level.number(), 0);
317 }
318
319 #[test]
320 fn test_has_rtl() {
321 assert_eq!(has_rtl(&Level::vec(&[0, 0, 0])), false);
322 assert_eq!(has_rtl(&Level::vec(&[0, 1, 0])), true);
323 assert_eq!(has_rtl(&Level::vec(&[0, 2, 0])), false);
324 assert_eq!(has_rtl(&Level::vec(&[0, 125, 0])), true);
325 assert_eq!(has_rtl(&Level::vec(&[0, 126, 0])), false);
326 }
327
328 #[test]
329 fn test_into() {
330 let level = Level::rtl();
331 assert_eq!(1u8, level.into());
332 }
333
334 #[test]
335 fn test_vec() {
336 assert_eq!(
337 Level::vec(&[0, 1, 125]),
338 vec![Level(0), Level(1), Level(125)]
339 );
340 }
341
342 #[test]
343 fn test_str_eq() {
344 assert_eq!(Level::vec(&[0, 1, 4, 125]), vec!["0", "1", "x", "125"]);
345 assert_ne!(Level::vec(&[0, 1, 4, 125]), vec!["0", "1", "5", "125"]);
346 }
347
348 #[test]
349 fn test_string_eq() {
350 assert_eq!(
351 Level::vec(&[0, 1, 4, 125]),
352 vec!["0".to_string(), "1".to_string(), "x".to_string(), "125".to_string()]
353 );
354 }
355}
356
357#[cfg(all(feature = "serde", test))]
358mod serde_tests {
359 use serde_test::{Token, assert_tokens};
360 use super::*;
361
362 #[test]
363 fn test_statics() {
364 assert_tokens(
365 &Level::ltr(),
366 &[Token::NewtypeStruct { name: "Level" }, Token::U8(0)],
367 );
368 assert_tokens(
369 &Level::rtl(),
370 &[Token::NewtypeStruct { name: "Level" }, Token::U8(1)],
371 );
372 }
373
374 #[test]
375 fn test_new() {
376 let level = Level::new(42).unwrap();
377 assert_tokens(
378 &level,
379 &[Token::NewtypeStruct { name: "Level" }, Token::U8(42)],
380 );
381 }
382}