1use crate::error::Error;
2use std::str::FromStr;
3
4#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Debug, Hash)]
6#[repr(u8)]
7pub enum Rank {
8 First = 0,
9 Second = 1,
10 Third = 2,
11 Fourth = 3,
12 Fifth = 4,
13 Sixth = 5,
14 Seventh = 6,
15 Eighth = 7,
16}
17
18pub const NUM_RANKS: usize = 8;
20
21pub const ALL_RANKS: [Rank; NUM_RANKS] = [Rank::First, Rank::Second, Rank::Third, Rank::Fourth, Rank::Fifth, Rank::Sixth, Rank::Seventh, Rank::Eighth];
23
24impl Rank {
25 #[inline]
28 pub fn from_index(i: usize) -> Rank {
29 match i & 7 {
31 0 => Rank::First,
32 1 => Rank::Second,
33 2 => Rank::Third,
34 3 => Rank::Fourth,
35 4 => Rank::Fifth,
36 5 => Rank::Sixth,
37 6 => Rank::Seventh,
38 7 => Rank::Eighth,
39 _ => unreachable!(),
40 }
41 }
42
43 #[inline]
45 pub fn down(&self) -> Rank {
46 Rank::from_index(self.to_index().wrapping_sub(1))
47 }
48
49 #[inline]
51 pub fn up(&self) -> Rank {
52 Rank::from_index(self.to_index() + 1)
53 }
54
55 #[inline]
57 pub fn to_index(self) -> usize {
58 self as usize
59 }
60}
61
62impl FromStr for Rank {
63 type Err = Error;
64
65 fn from_str(s: &str) -> Result<Self, Self::Err> {
66 if s.is_empty() {
67 return Err(Error::InvalidRank);
68 }
69 match s.chars().next().unwrap() {
70 '1' => Ok(Rank::First),
71 '2' => Ok(Rank::Second),
72 '3' => Ok(Rank::Third),
73 '4' => Ok(Rank::Fourth),
74 '5' => Ok(Rank::Fifth),
75 '6' => Ok(Rank::Sixth),
76 '7' => Ok(Rank::Seventh),
77 '8' => Ok(Rank::Eighth),
78 _ => Err(Error::InvalidRank),
79 }
80 }
81}