blunders_engine/
error.rs

1//! Blunders Engine error type.
2
3use std::error;
4use std::fmt::{self, Display};
5use std::result;
6
7use crate::fen::ParseFenError;
8
9/// Blunders Engine generic result type.
10pub type Result<T> = result::Result<T, Error>;
11
12/// A list specifying general errors for Blunders engine.
13#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash, Ord, PartialOrd)]
14#[non_exhaustive]
15pub enum ErrorKind {
16    /// An argument was expected following a string key, but none was provided.
17    UciNoArgument,
18    /// Uci failed to parse an integer type.
19    UciCannotParseInt,
20    /// Uci received an unsupported option.
21    UciInvalidOption,
22    /// Uci received an unknown command.
23    UciUnknownCommand,
24    /// Uci received no command string.
25    UciNoCommand,
26    /// Uci debug missing mode.
27    UciDebugNoMode,
28    /// Uci debug illegal mode.
29    UciDebugIllegalMode,
30    /// No name provided for Uci setoption command.
31    UciSetOptionNoName,
32    /// Uci position command malformed.
33    UciPositionMalformed,
34    /// Uci position command given illegal move.
35    UciPositionIllegalMove,
36    /// Uci Option fails to update.
37    UciOptionCannotUpdate,
38    /// Fen error kinds.
39    Fen,
40
41    /// Square parse string malformed.
42    ParseSquareMalformed,
43    /// File parse string malformed.
44    ParseFileMalformed,
45    /// Rank parse string malformed.
46    ParseRankMalformed,
47    /// Color parse string malformed.
48    ParseColorMalformed,
49    /// Piece parse string malformed.
50    ParsePieceMalformed,
51    /// Piece parse string malformed.
52    ParseCastlingMalformed,
53
54    /// Time Management Mode cannot be created, missing fields.
55    ModeNotSatisfied,
56
57    /// The engine can only play games with a finite static number of moves.
58    /// That limit has been exceeded.
59    MoveHistoryExceeded,
60
61    /// Engine's transposition table is being referenced from another thread.
62    EngineTranspositionTableInUse,
63    /// Engine is currently searching, so another search cannot be started.
64    EngineAlreadySearching,
65
66    // An illegal move was provided, and could not be applied to some base position.
67    GameIllegalMove,
68}
69
70impl ErrorKind {
71    pub fn as_str(&self) -> &'static str {
72        match self {
73            ErrorKind::UciNoArgument => "uci no argument",
74            ErrorKind::UciCannotParseInt => "uci cannot parse integer",
75            ErrorKind::UciInvalidOption => "uci invalid option",
76            ErrorKind::UciUnknownCommand => "uci unknown command",
77            ErrorKind::UciNoCommand => "uci no command",
78            ErrorKind::UciDebugNoMode => "uci debug no mode",
79            ErrorKind::UciDebugIllegalMode => "uci debug illegal mode",
80            ErrorKind::UciSetOptionNoName => "uci setoption no name",
81            ErrorKind::UciPositionMalformed => "uci position malformed",
82            ErrorKind::UciPositionIllegalMove => "uci position illegal move",
83            ErrorKind::UciOptionCannotUpdate => "uci option cannot update",
84            ErrorKind::Fen => "fen",
85
86            ErrorKind::ParseSquareMalformed => "parse square malformed",
87            ErrorKind::ParseFileMalformed => "parse file malformed",
88            ErrorKind::ParseRankMalformed => "parse rank malformed",
89            ErrorKind::ParseColorMalformed => "parse color malformed",
90            ErrorKind::ParsePieceMalformed => "parse piece malformed",
91            ErrorKind::ParseCastlingMalformed => "parse castling malformed",
92
93            ErrorKind::ModeNotSatisfied => "mode not satisfied",
94
95            ErrorKind::MoveHistoryExceeded => "move history exceeded",
96
97            ErrorKind::EngineTranspositionTableInUse => "engine transposition table in use",
98            ErrorKind::EngineAlreadySearching => "engine already searching",
99
100            ErrorKind::GameIllegalMove => "position history illegal move",
101        }
102    }
103}
104
105impl Display for ErrorKind {
106    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
107        write!(f, "{}", self.as_str())
108    }
109}
110
111/// The primary and general error type for the Blunders Engine.
112#[derive(Debug)]
113pub enum Error {
114    Simple(ErrorKind),
115    Message(ErrorKind, String),
116    Custom(ErrorKind, Box<dyn error::Error + Send + Sync>),
117}
118
119impl Error {
120    pub fn new<E>(error_kind: ErrorKind, inner_error: E) -> Self
121    where
122        E: Into<Box<dyn error::Error + Send + Sync>>,
123    {
124        Self::Custom(error_kind, inner_error.into())
125    }
126}
127
128impl Display for Error {
129    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
130        match self {
131            Error::Simple(error_kind) => {
132                write!(f, "{}", error_kind)
133            }
134            Error::Message(error_kind, string) => {
135                write!(f, "{}: {}", error_kind, string)
136            }
137            Error::Custom(error_kind, ref box_error) => {
138                write!(f, "{}, error: {}", error_kind, *box_error)
139            }
140        }
141    }
142}
143
144impl error::Error for Error {}
145
146impl From<ErrorKind> for Error {
147    fn from(error_kind: ErrorKind) -> Self {
148        Self::Simple(error_kind)
149    }
150}
151
152impl From<ParseFenError> for Error {
153    fn from(error: ParseFenError) -> Self {
154        Self::Custom(ErrorKind::Fen, error.into())
155    }
156}
157
158impl<S: ToString> From<(ErrorKind, S)> for Error {
159    fn from((error_kind, stringable): (ErrorKind, S)) -> Self {
160        Self::Message(error_kind, stringable.to_string())
161    }
162}