1use crate::error::Error;
2use std::str::FromStr;
3
4#[repr(u8)]
6#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Debug, Hash)]
7pub enum File {
8 A = 0,
9 B = 1,
10 C = 2,
11 D = 3,
12 E = 4,
13 F = 5,
14 G = 6,
15 H = 7,
16}
17
18pub const NUM_FILES: usize = 8;
20
21pub const ALL_FILES: [File; NUM_FILES] = [File::A, File::B, File::C, File::D, File::E, File::F, File::G, File::H];
23
24impl File {
25 #[inline]
27 pub fn from_index(i: usize) -> File {
28 match i & 7 {
30 0 => File::A,
31 1 => File::B,
32 2 => File::C,
33 3 => File::D,
34 4 => File::E,
35 5 => File::F,
36 6 => File::G,
37 7 => File::H,
38 _ => unreachable!(),
39 }
40 }
41
42 #[inline]
44 pub fn left(&self) -> File {
45 File::from_index(self.to_index().wrapping_sub(1))
46 }
47
48 #[inline]
50 pub fn right(&self) -> File {
51 File::from_index(self.to_index() + 1)
52 }
53
54 #[inline]
56 pub fn to_index(self) -> usize {
57 self as usize
58 }
59}
60
61impl FromStr for File {
62 type Err = Error;
63
64 fn from_str(s: &str) -> Result<Self, Self::Err> {
65 if s.is_empty() {
66 return Err(Error::InvalidFile);
67 }
68 match s.chars().next().unwrap() {
69 'a' => Ok(File::A),
70 'b' => Ok(File::B),
71 'c' => Ok(File::C),
72 'd' => Ok(File::D),
73 'e' => Ok(File::E),
74 'f' => Ok(File::F),
75 'g' => Ok(File::G),
76 'h' => Ok(File::H),
77 _ => Err(Error::InvalidFile),
78 }
79 }
80}