chess_notation_parser/
castling.rs

1//! A simple castling representation
2
3use crate::flag::{Flag, FlagCheck};
4use std::fmt;
5
6/// Castling type (side)
7#[derive(Copy, Clone, Debug, PartialEq, Eq)]
8pub enum CastlingType {
9    /// Sometimes referred to as *castling queenside*
10    Long,
11
12    /// Sometimes referred to as *castling kingside*
13    Short,
14}
15
16impl CastlingType {
17    /// Return opposite castling type
18    pub fn opposite(&self) -> Self {
19        match self {
20            Self::Short => Self::Long,
21            Self::Long => Self::Short,
22        }
23    }
24}
25
26impl fmt::Display for CastlingType {
27    #[rustfmt::skip]
28    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
29        write!(f, "{}", match self {
30                Self::Long => "0-0-0",
31                Self::Short => "0-0",
32            }
33        )
34    }
35}
36
37/// # Castling turn
38///
39/// In chess, castling is a special move where a King can move two squares
40/// either to the left (Kingside Castle) or right (Queenside Castle).  The rook
41/// is then placed to the left or right of the King respectively.
42///
43/// ## Example
44/// ```
45/// use chess_notation_parser::{Turn, Castling, CastlingType, Flag};
46///
47/// let turn = Turn::Castling(
48///     Castling {
49///         r#type: CastlingType::Short,
50///         flags: Flag::CHECK,
51///     }
52/// );
53///
54/// assert_eq!(turn, Turn::try_from("0-0+").unwrap());
55/// ```
56#[derive(Copy, Clone, Debug, PartialEq)]
57pub struct Castling {
58    /// Castling type (side)
59    pub r#type: CastlingType,
60
61    /// Extra bits of information stored in a bitmask about the turn, check
62    /// `Flag` for more info
63    pub flags: u8,
64}
65
66impl FlagCheck for Castling {
67    fn get_flags(&self) -> u8 {
68        self.flags
69    }
70}
71
72impl fmt::Display for Castling {
73    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
74        match self.flags {
75            Flag::NONE => write!(f, "{}", self.r#type),
76            Flag::CHECK => write!(f, "{}+", self.r#type),
77            Flag::CHECKMATE => write!(f, "{}#", self.r#type),
78            _ => panic!("Invalid flag used for castling struct"),
79        }
80    }
81}
82
83#[cfg(test)]
84mod tests {
85    use super::*;
86
87    #[test]
88    fn opposite_castling_type() {
89        let short = CastlingType::Short;
90        let long = CastlingType::Long;
91
92        assert_eq!(short, long.opposite());
93        assert_eq!(short, short.opposite().opposite());
94
95        assert_eq!(long, short.opposite());
96        assert_eq!(long, long.opposite().opposite());
97    }
98}