fast_tak/
error.rs

1use std::{error::Error, fmt::Display};
2
3#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord)]
4pub enum PlayError {
5    OutOfBounds,
6    AlreadyOccupied,
7    NoCapstone,
8    NoStones,
9    OpeningNonFlat,
10    EmptySquare,
11    StackNotOwned,
12    StackError(StackError),
13    TakeError(TakeError),
14    SpreadOutOfBounds,
15    GameOver,
16}
17
18impl Display for PlayError {
19    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
20        if let Self::StackError(stack_error) = self {
21            stack_error.fmt(f)
22        } else if let Self::TakeError(take_error) = self {
23            take_error.fmt(f)
24        } else {
25            match self {
26                Self::OutOfBounds => "given square is not on the board",
27                Self::AlreadyOccupied => {
28                    "cannot place a piece in that position because it is already occupied"
29                }
30                Self::NoCapstone => "there is not a capstone left to play",
31                Self::NoStones => "there are no more stones left to play",
32                Self::OpeningNonFlat => "cannot play a wall or capstone on the first two plies",
33                Self::EmptySquare => "cannot move from an empty square",
34                Self::StackNotOwned => "cannot move a stack that you do not own",
35                Self::SpreadOutOfBounds => "spread would leave the board",
36                Self::GameOver => "cannot play a move after the game is over",
37                Self::StackError(_) | Self::TakeError(_) => unreachable!(),
38            }
39            .fmt(f)
40        }
41    }
42}
43
44impl Error for PlayError {}
45
46impl From<TakeError> for PlayError {
47    fn from(e: TakeError) -> Self {
48        Self::TakeError(e)
49    }
50}
51
52impl From<StackError> for PlayError {
53    fn from(e: StackError) -> Self {
54        Self::StackError(e)
55    }
56}
57
58#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord)]
59pub enum StackError {
60    Wall,
61    Cap,
62}
63
64impl Display for StackError {
65    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
66        match self {
67            Self::Cap => "cannot stack on top of a capstone",
68            Self::Wall => "can only flatten a wall with a capstone",
69        }
70        .fmt(f)
71    }
72}
73
74impl Error for StackError {}
75
76#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord)]
77pub enum TakeError {
78    Zero,
79    CarryLimit,
80    StackSize,
81}
82
83impl Display for TakeError {
84    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
85        match self {
86            Self::Zero => "cannot take 0 from a stack",
87            Self::CarryLimit => "cannot take more than the carry limit",
88            Self::StackSize => "cannot take more pieces than there are on the stack",
89        }
90        .fmt(f)
91    }
92}
93
94impl Error for TakeError {}