1use std::error;
4use std::fmt::{self, Display};
5use std::result;
6
7use crate::fen::ParseFenError;
8
9pub type Result<T> = result::Result<T, Error>;
11
12#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash, Ord, PartialOrd)]
14#[non_exhaustive]
15pub enum ErrorKind {
16 UciNoArgument,
18 UciCannotParseInt,
20 UciInvalidOption,
22 UciUnknownCommand,
24 UciNoCommand,
26 UciDebugNoMode,
28 UciDebugIllegalMode,
30 UciSetOptionNoName,
32 UciPositionMalformed,
34 UciPositionIllegalMove,
36 UciOptionCannotUpdate,
38 Fen,
40
41 ParseSquareMalformed,
43 ParseFileMalformed,
45 ParseRankMalformed,
47 ParseColorMalformed,
49 ParsePieceMalformed,
51 ParseCastlingMalformed,
53
54 ModeNotSatisfied,
56
57 MoveHistoryExceeded,
60
61 EngineTranspositionTableInUse,
63 EngineAlreadySearching,
65
66 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#[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}