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