1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
use crate::bidi_class::BidiClass;
use crate::direction::Direction;
use crate::NO_LEVEL;

/// Maximum stack depth; UBA guarantees that it will never increase
/// in later versions of the spec.
pub const MAX_DEPTH: usize = 125;

#[derive(Default, Clone, Copy, Debug, Eq, PartialEq, Ord, PartialOrd, Hash)]
pub struct Level(pub i8);

impl Level {
    pub fn direction(self) -> Direction {
        Direction::with_level(self.0)
    }

    pub fn as_bidi_class(self) -> BidiClass {
        if self.0 % 2 == 1 {
            BidiClass::RightToLeft
        } else {
            BidiClass::LeftToRight
        }
    }

    pub fn removed_by_x9(self) -> bool {
        self.0 == NO_LEVEL
    }

    pub fn max(self, other: Level) -> Level {
        Level(self.0.max(other.0))
    }

    pub(crate) fn least_greater_even(self) -> Option<Level> {
        let level = if self.0 % 2 == 0 {
            self.0 + 2
        } else {
            self.0 + 1
        };
        if level as usize > MAX_DEPTH {
            None
        } else {
            Some(Self(level))
        }
    }

    pub(crate) fn least_greater_odd(self) -> Option<Level> {
        let level = if self.0 % 2 == 1 {
            self.0 + 2
        } else {
            self.0 + 1
        };
        if level as usize > MAX_DEPTH {
            None
        } else {
            Some(Self(level))
        }
    }
}