easychess_lib/pieces.rs
1use std::fmt::Debug;
2
3/// Error for when [Piece::try_from] gets an invalid [char].
4pub struct TryFromError(char, u32, &'static str);
5
6impl Debug for TryFromError {
7 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
8 write!(
9 f,
10 "invalid char '{}' at line {} in file {}",
11 self.0, self.1, self.2
12 )
13 }
14}
15
16#[derive(Clone, Copy)]
17pub enum PieceType {
18 King,
19 Queen,
20 Rook,
21 Bishop,
22 Knight,
23 Pawn,
24}
25
26#[derive(Clone, Copy)]
27pub enum PieceTeam {
28 White(PieceType),
29 Black(PieceType),
30 None,
31}
32
33/// Is placed on [crate::board::Board]
34#[derive(Clone, Copy)]
35pub struct Piece(PieceTeam);
36impl Piece {
37 /// Piece struct with [PieceTeam::None]
38 pub const NONE: Self = Self(PieceTeam::None);
39}
40
41impl TryFrom<char> for Piece {
42 type Error = TryFromError;
43 /// Matches a [char] that represents a chess piece to a [Piece].
44 /// Valid chars are:
45 /// ```no_run
46 /// '.' => return PieceTeam::None
47 /// 'k' => PieceType::King,
48 /// 'q' => PieceType::Queen,
49 /// 'r' => PieceType::Rook,
50 /// 'b' => PieceType::Bishop,
51 /// 'n' => PieceType::Knight,
52 /// 'p' => PieceType::Pawn,
53 /// ```
54 /// Matches uppercase and lowercase to [PieceTeam]:
55 /// ```no_run
56 /// true => PieceTeam::White(ptype),
57 /// false => PieceTeam::Black(ptype),
58 /// ```
59 ///
60 /// # Errors
61 /// Invalid chars return:
62 /// ```
63 /// Err(TryFromError(c, line!(), module_path!()))
64 /// ```
65 fn try_from(value: char) -> Result<Self, Self::Error> {
66 let ptype = match value.to_ascii_lowercase() {
67 '.' => return Ok(Self(PieceTeam::None)),
68 'k' => PieceType::King,
69 'q' => PieceType::Queen,
70 'r' => PieceType::Rook,
71 'b' => PieceType::Bishop,
72 'n' => PieceType::Knight,
73 'p' => PieceType::Pawn,
74 //' ' | '.' => PieceType::None,
75 c => return Err(TryFromError(c, line!(), module_path!())),
76 };
77 let pteam = match value.is_ascii_uppercase() {
78 true => PieceTeam::White(ptype),
79 false => PieceTeam::Black(ptype),
80 };
81 Ok(Self(pteam))
82 }
83}
84impl Into<char> for Piece {
85 /// Matches a [PieceType] variant to a [char] that represents a chess piece:
86 /**
87 ```
88 PieceType::None => return '.',
89 PieceType::King => 'k',
90 PieceType::Queen => 'q',
91 PieceType::Rook => 'r',
92 PieceType::Bishop => 'b',
93 PieceType::Knight => 'n',
94 PieceType::Pawn => 'p',
95 ```
96 */
97 ///
98 fn into(self) -> char {
99 // let matched_char = match self.piece_type {
100 // PieceType::King => 'k',
101 // PieceType::Queen => 'q',
102 // PieceType::Rook => 'r',
103 // PieceType::Bishop => 'b',
104 // PieceType::Knight => 'n',
105 // PieceType::Pawn => 'p',
106 // PieceType::None => '.',
107 // };
108 // match self.piece_team {
109 // PieceTeam::White => matched_char.to_ascii_uppercase(),
110 // _ => matched_char,
111 // }
112 let matched_char = match self.0 {
113 PieceTeam::None => return '.',
114 PieceTeam::White(ptype) | PieceTeam::Black(ptype) => match ptype {
115 PieceType::King => 'k',
116 PieceType::Queen => 'q',
117 PieceType::Rook => 'r',
118 PieceType::Bishop => 'b',
119 PieceType::Knight => 'n',
120 PieceType::Pawn => 'p',
121 },
122 };
123 match self.0 {
124 PieceTeam::White(_) => matched_char.to_ascii_uppercase(),
125 _ => matched_char,
126 }
127 }
128}
129//TODO: impl display sometime