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 File {
7 A = 0,
8 B = 1,
9 C = 2,
10 D = 3,
11 E = 4,
12 F = 5,
13 G = 6,
14 H = 7,
15}
16
17impl File {
18 #[inline]
19 pub const fn from_int(i: u8) -> Self {
20 unsafe { std::mem::transmute(i) }
21 }
22
23 #[inline]
24 pub const fn from_index(i: usize) -> Self {
25 Self::from_int(i as u8)
26 }
27
28 #[inline]
29 pub fn left(self) -> Option<Self> {
30 *get_item_unchecked!(
31 const {
32 [
33 None,
34 Some(Self::A),
35 Some(Self::B),
36 Some(Self::C),
37 Some(Self::D),
38 Some(Self::E),
39 Some(Self::F),
40 Some(Self::G),
41 ]
42 },
43 self.to_index(),
44 )
45 }
46
47 #[inline]
48 pub fn right(self) -> Option<Self> {
49 *get_item_unchecked!(
50 const {
51 [
52 Some(Self::B),
53 Some(Self::C),
54 Some(Self::D),
55 Some(Self::E),
56 Some(Self::F),
57 Some(Self::G),
58 Some(Self::H),
59 None,
60 ]
61 },
62 self.to_index(),
63 )
64 }
65
66 #[inline]
67 pub fn wrapping_left(self) -> Self {
68 self.left().unwrap_or(Self::H)
69 }
70
71 #[inline]
72 pub fn wrapping_right(self) -> Self {
73 self.right().unwrap_or(Self::A)
74 }
75
76 #[inline]
77 pub const fn to_int(self) -> u8 {
78 self as u8
79 }
80
81 #[inline]
82 pub const fn to_index(self) -> usize {
83 self as usize
84 }
85
86 #[inline]
87 pub fn to_bitboard(self) -> BitBoard {
88 *get_item_unchecked!(BB_FILES, self.to_index())
89 }
90
91 #[inline]
92 pub fn get_adjacent_files_bb(self) -> BitBoard {
93 *get_item_unchecked!(BB_ADJACENT_FILES, self.to_index())
94 }
95}
96
97impl FromStr for File {
98 type Err = TimecatError;
99
100 fn from_str(s: &str) -> Result<Self> {
101 match s.to_lowercase().trim() {
102 "a" => Ok(Self::A),
103 "b" => Ok(Self::B),
104 "c" => Ok(Self::C),
105 "d" => Ok(Self::D),
106 "e" => Ok(Self::E),
107 "f" => Ok(Self::F),
108 "g" => Ok(Self::G),
109 "h" => Ok(Self::H),
110 _ => Err(TimecatError::InvalidFileString { s: s.to_string() }),
111 }
112 }
113}