chess_turn_engine/game/
game_error.rs

1use super::gamestate::Gamestate;
2use std::error;
3use std::fmt;
4
5/// Error codes
6#[derive(Debug, PartialEq)]
7pub enum GameError {
8    /// Origin square not found for moving piece
9    MovingPieceNotFound,
10
11    /// Unexpected king state for the turn
12    KingIsSafe,
13
14    /// Unexpected king state for the turn
15    KingIsInCheck,
16
17    /// Unexpected king state for the turn
18    KingIsInCheckmate,
19
20    /// King movement during castling must not be under check
21    KingCannotCastleSafetly,
22
23    /// Upon executing the turn, king must remain safe
24    OurKingMustBeSafe,
25
26    /// Turn missing info about the capture
27    CaptureNotSet,
28
29    /// Capture of an ally piece is not allowed
30    CaptureAlly,
31
32    /// Capture expected, but capture piece missing on the board on the
33    /// destination square
34    NoCapturePiece,
35
36    /// Game over
37    GameOver(Gamestate),
38
39    /// King can castle if it is not under check
40    CastlingUnderCheck,
41
42    /// Castling not possible
43    ///  - Maybe king/rook has moved already and doing so made castling
44    ///  unavailable
45    CastlingUnavailable,
46
47    /// Squares between a rook and a king must be empty in order to perform
48    /// castling turn
49    CastlingSquaresNotEmpty,
50
51    /// Pawn moves:
52    ///  - diagonally only by capture action
53    ///  - straight in case of no capture action
54    InvalidPawnMovement,
55
56    /// Turn notation is not correct
57    ParsingTurnFailed,
58
59    /// Undo unavailable
60    UndoNotAvailable,
61}
62
63impl error::Error for GameError {}
64
65impl fmt::Display for GameError {
66    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
67        write!(f, "{}", self.get_str())
68    }
69}
70
71impl GameError {
72    fn get_str(&self) -> String {
73        match self {
74            Self::MovingPieceNotFound => {
75                "Source square not found for the moving piece".to_string()
76            }
77            Self::NoCapturePiece => {
78                "Nothing to capture, dst square empty".to_string()
79            }
80            Self::KingIsInCheck => "Invalid turn: King is in check".to_string(),
81            Self::KingIsInCheckmate => {
82                "Invalid turn: King is in checkmate".to_string()
83            }
84            Self::OurKingMustBeSafe => {
85                "Invalid turn: Our king is in check".to_string()
86            }
87            Self::CaptureNotSet => {
88                "Invalid turn: Unexpected capture".to_string()
89            }
90            Self::CaptureAlly => {
91                "Capturing ally pieces not allowed".to_string()
92            }
93            Self::CastlingUnavailable => "Castling not available".to_string(),
94            Self::GameOver(gamestate) => format!("Game over: {}", gamestate),
95            Self::CastlingUnderCheck => {
96                "King under check cannot castle check".to_string()
97            }
98            Self::KingCannotCastleSafetly => {
99                "King cannot safetly perform castling".to_string()
100            }
101            Self::CastlingSquaresNotEmpty => {
102                "Squares between rook and king must be empty for castling"
103                    .to_string()
104            }
105            Self::KingIsSafe => {
106                "Invalid turn: King not supposed to be safe".to_string()
107            }
108            Self::InvalidPawnMovement => {
109                "Pawns move diagonally only by capture".to_string()
110            }
111            Self::ParsingTurnFailed => "Parsing turn failed".to_string(),
112            Self::UndoNotAvailable => "Undo not available".to_string(),
113        }
114    }
115}
116
117#[cfg(test)]
118mod tests {
119    use super::*;
120
121    #[test]
122    fn print() {
123        let errors = [
124            GameError::MovingPieceNotFound,
125            GameError::KingIsSafe,
126            GameError::KingIsInCheck,
127            GameError::KingIsInCheckmate,
128            GameError::KingCannotCastleSafetly,
129            GameError::OurKingMustBeSafe,
130            GameError::CaptureNotSet,
131            GameError::CaptureAlly,
132            GameError::NoCapturePiece,
133            GameError::GameOver(Gamestate::Ongoing),
134            GameError::CastlingUnderCheck,
135            GameError::CastlingUnavailable,
136            GameError::CastlingSquaresNotEmpty,
137            GameError::InvalidPawnMovement,
138            GameError::ParsingTurnFailed,
139            GameError::UndoNotAvailable,
140        ];
141
142        errors.iter().for_each(|err| {
143            // Unit test coverage test
144            err.to_string();
145        });
146    }
147}