chess_lab/common/errors/position.rs
1use thiserror::Error;
2
3use crate::core::Position;
4
5/// Error indicating that a specific [Position] is already occupied
6///
7#[derive(Debug, Error)]
8#[error("Position {position} is already occupied")]
9pub struct PositionOccupiedError {
10 /// The [Position] that is already occupied
11 pub position: Position,
12}
13
14impl PositionOccupiedError {
15 /// Creates a new [PositionOccupiedError] with the given [Position]
16 ///
17 /// # Arguments
18 /// * `position` - The [Position] that is occupied
19 ///
20 /// # Example
21 /// ```
22 /// # use chess_lab::errors::PositionOccupiedError;
23 /// use chess_lab::core::Position;
24 ///
25 /// let position = Position::from_string("a1").unwrap();
26 /// let error = PositionOccupiedError::new(position);
27 /// ```
28 ///
29 pub fn new(position: Position) -> Self {
30 PositionOccupiedError { position }
31 }
32}
33
34/// Error indicating that a specific [Position] is empty
35///
36#[derive(Debug, Error)]
37#[error("Position {position} is empty")]
38pub struct PositionEmptyError {
39 /// The [Position] that is empty
40 pub position: Position,
41}
42
43impl PositionEmptyError {
44 /// Creates a new [PositionEmptyError] with the given [Position]
45 ///
46 /// # Arguments
47 /// * `position` - The [Position] that is empty
48 ///
49 /// # Example
50 /// ```
51 /// # use chess_lab::errors::PositionEmptyError;
52 /// use chess_lab::core::Position;
53 ///
54 /// let position = Position::from_string("a1").unwrap();
55 /// let error = PositionEmptyError::new(position);
56 /// ```
57 ///
58 pub fn new(position: Position) -> Self {
59 PositionEmptyError { position }
60 }
61}
62
63/// Error indicating that a [Position] is out of the allowed range
64///
65#[derive(Debug, PartialEq, Error)]
66#[error("Position ({col}, {row}) is out of range")]
67pub struct PositionOutOfRangeError {
68 /// The column index that is out of range
69 pub col: u8,
70 /// The row index that is out of range
71 pub row: u8,
72}
73
74impl PositionOutOfRangeError {
75 /// Creates a new [PositionOutOfRangeError] with the given column and row
76 ///
77 /// # Arguments
78 /// * `col` - The column index that is out of range
79 /// * `row` - The row index that is out of range
80 ///
81 /// # Example
82 /// ```
83 /// # use chess_lab::errors::PositionOutOfRangeError;
84 /// let col = 8;
85 /// let row = 8;
86 /// let error = PositionOutOfRangeError::new(col, row);
87 /// ```
88 ///
89 pub fn new(col: u8, row: u8) -> Self {
90 PositionOutOfRangeError { col, row }
91 }
92}
93
94/// Error indicating that a [Position] is invalid
95///
96#[derive(Debug, PartialEq, Error)]
97#[error("Invalid position: {position_str}")]
98pub struct PositionInvalidError {
99 /// The string representation of the [Position] that is invali
100 pub position_str: String,
101}
102
103impl PositionInvalidError {
104 /// Creates a new [PositionInvalidError] with the given message
105 ///
106 /// # Arguments
107 /// * `message` - The message that describes the error
108 ///
109 /// # Example
110 /// ```
111 /// # use chess_lab::errors::PositionInvalidError;
112 /// let error = PositionInvalidError::new("Invalid position".to_string());
113 /// ```
114 ///
115 pub fn new(position_str: String) -> Self {
116 PositionInvalidError { position_str }
117 }
118}
119
120/// Error indicating that two [Positions](Position) are not aligned
121///
122#[derive(Debug, PartialEq, Error)]
123#[error("Positions {position1} and {position2} are not aligned")]
124pub struct UnalignedPositionsError {
125 /// The first [Position] that is not aligned
126 pub position1: Position,
127 /// The second [Position] that is not aligned
128 pub position2: Position,
129}
130
131impl UnalignedPositionsError {
132 /// Creates a new [UnalignedPositionsError] with the given positions
133 ///
134 /// # Arguments
135 /// * `position1` - The first [Position] that is not aligned
136 /// * `position2` - The second [Position] that is not aligned
137 ///
138 /// # Example
139 /// ```
140 /// # use chess_lab::errors::UnalignedPositionsError;
141 /// use chess_lab::core::Position;
142 ///
143 /// let position1 = Position::from_string("a1").unwrap();
144 /// let position2 = Position::from_string("b3").unwrap();
145 ///
146 /// let error = UnalignedPositionsError::new(position1, position2);
147 /// ```
148 ///
149 pub fn new(position1: Position, position2: Position) -> Self {
150 UnalignedPositionsError {
151 position1,
152 position2,
153 }
154 }
155}
156
157/// Error types for [Position] between operations
158///
159#[non_exhaustive]
160#[derive(Debug, PartialEq, Error)]
161pub enum PositionBetweenError {
162 /// Indicates that two [Positions](Position) are not aligned and they should be
163 #[error(transparent)]
164 Unaligned(#[from] UnalignedPositionsError),
165}
166
167#[cfg(test)]
168mod tests {
169 use super::*;
170
171 #[test]
172 fn test_position_occupied_error() {
173 let position = Position::from_string("a1").unwrap();
174 let error = PositionOccupiedError::new(position);
175
176 assert_eq!(error.position, position);
177 assert_eq!(format!("{}", error), "Position a1 is already occupied");
178 }
179
180 #[test]
181 fn test_position_empty_error() {
182 let position = Position::from_string("a1").unwrap();
183 let error = PositionEmptyError::new(position);
184
185 assert_eq!(error.position, position);
186 assert_eq!(format!("{}", error), "Position a1 is empty");
187 }
188
189 #[test]
190 fn test_position_out_of_range_error() {
191 let col = 8;
192 let row = 8;
193 let error = PositionOutOfRangeError::new(col, row);
194
195 assert_eq!(error.col, col);
196 assert_eq!(error.row, row);
197 assert_eq!(format!("{}", error), "Position (8, 8) is out of range");
198 }
199
200 #[test]
201 fn test_position_invalid_error() {
202 let position_str = "abc".to_string();
203 let error = PositionInvalidError::new(position_str.clone());
204
205 assert_eq!(error.position_str, position_str);
206 assert_eq!(format!("{}", error), "Invalid position: abc");
207 }
208
209 #[test]
210 fn test_unaligned_positions_error() {
211 let position1 = Position::from_string("a1").unwrap();
212 let position2 = Position::from_string("b3").unwrap();
213 let error = UnalignedPositionsError {
214 position1,
215 position2,
216 };
217
218 assert_eq!(error.position1, position1);
219 assert_eq!(error.position2, position2);
220 assert_eq!(format!("{}", error), "Positions a1 and b3 are not aligned");
221 }
222}