timecat/utils/
ranks.rs

1use super::*;
2
3#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
4#[repr(u8)]
5#[derive(PartialEq, Eq, PartialOrd, Ord, Clone, Copy, Debug, Hash)]
6pub enum Rank {
7    First = 0,
8    Second = 1,
9    Third = 2,
10    Fourth = 3,
11    Fifth = 4,
12    Sixth = 5,
13    Seventh = 6,
14    Eighth = 7,
15}
16
17impl Rank {
18    #[inline]
19    pub const unsafe fn from_int(i: u8) -> Self {
20        std::mem::transmute(i)
21    }
22
23    #[inline]
24    pub const unsafe fn from_index(i: usize) -> Self {
25        Self::from_int(i as u8)
26    }
27
28    #[inline]
29    pub fn up(self) -> Option<Self> {
30        (self != Self::Eighth).then(|| unsafe { Self::from_int(self.to_int() + 1) })
31    }
32
33    #[inline]
34    pub fn down(self) -> Option<Self> {
35        (self != Self::First).then(|| unsafe { Self::from_int(self.to_int() - 1) })
36    }
37
38    #[inline]
39    pub fn wrapping_up(self) -> Self {
40        self.up().unwrap_or(Self::First)
41    }
42
43    #[inline]
44    pub fn wrapping_down(self) -> Self {
45        self.down().unwrap_or(Self::Eighth)
46    }
47
48    #[inline]
49    pub const fn to_int(self) -> u8 {
50        self as u8
51    }
52
53    #[inline]
54    pub const fn to_index(self) -> usize {
55        self as usize
56    }
57
58    #[inline]
59    pub const fn to_bitboard(self) -> BitBoard {
60        BitBoard::new(0xff << (self.to_int() << 3))
61    }
62
63    #[inline]
64    pub fn get_upper_board_mask(self, color: Color) -> BitBoard {
65        *get_item_unchecked!(UPPER_BOARD_MASK, color.to_index(), self.to_index())
66    }
67
68    #[inline]
69    pub fn get_lower_board_mask(self, color: Color) -> BitBoard {
70        self.get_upper_board_mask(!color)
71    }
72}
73
74impl fmt::Display for Rank {
75    #[inline]
76    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
77        write!(f, "{}", self.to_int() + 1)
78    }
79}
80
81impl TryFrom<char> for Rank {
82    type Error = TimecatError;
83
84    #[inline]
85    fn try_from(c: char) -> Result<Self> {
86        match c {
87            '1' => Ok(Self::First),
88            '2' => Ok(Self::Second),
89            '3' => Ok(Self::Third),
90            '4' => Ok(Self::Fourth),
91            '5' => Ok(Self::Fifth),
92            '6' => Ok(Self::Sixth),
93            '7' => Ok(Self::Seventh),
94            '8' => Ok(Self::Eighth),
95            _ => Err(TimecatError::InvalidRankString {
96                s: c.to_string().into(),
97            }),
98        }
99    }
100}
101
102impl FromStr for Rank {
103    type Err = TimecatError;
104
105    #[inline]
106    fn from_str(s: &str) -> Result<Self> {
107        match s.trim() {
108            "1" => Ok(Self::First),
109            "2" => Ok(Self::Second),
110            "3" => Ok(Self::Third),
111            "4" => Ok(Self::Fourth),
112            "5" => Ok(Self::Fifth),
113            "6" => Ok(Self::Sixth),
114            "7" => Ok(Self::Seventh),
115            "8" => Ok(Self::Eighth),
116            _ => Err(TimecatError::InvalidRankString {
117                s: s.to_string().into(),
118            }),
119        }
120    }
121}