Skip to content

Commit 3d3bf49

Browse files
committed
vis and less unwraps
1 parent 4aaa50b commit 3d3bf49

2 files changed

Lines changed: 52 additions & 35 deletions

File tree

src/notation/fen.rs

Lines changed: 40 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,11 @@ struct FenStrings {
3232
pub enum GameFromFenError {
3333
NotAscii,
3434
WrongFieldCount,
35+
MalformedBoard(BoardFromFenError),
36+
MalformedPlayer(InvalidPlayer),
37+
MalformedEnPassantTarget(SquareFromFenError),
38+
MalformedFiftyRuleClock(core::num::ParseIntError),
39+
MalformedMoveCount(core::num::ParseIntError),
3540
}
3641
impl GameStateCore {
3742
pub fn try_from_fen(fen: &str) -> Result<Self, GameFromFenError> {
@@ -56,18 +61,23 @@ impl GameStateCore {
5661
full_move_number: fen_parts[5].clone(),
5762
};
5863

59-
let board = Board::try_from_fen_repr(fen.piece_placements.as_slice()).unwrap();
64+
let board = Board::try_from_fen_repr(fen.piece_placements.as_slice())
65+
.map_err(GameFromFenError::MalformedBoard)?;
6066

6167
let fifty_move_rule_clock =
62-
FiftyMoveRuleClock::try_from_fen_repr(fen.half_move_clock.as_slice()).unwrap();
68+
FiftyMoveRuleClock::try_from_fen_repr(fen.half_move_clock.as_slice())
69+
.map_err(GameFromFenError::MalformedFiftyRuleClock)?;
6370

6471
let castling_rights = CastlingRights::from_fen_repr(&fen.castling_availability);
6572

66-
let active_player = PlayerKind::try_from_fen_repr(fen.active_player.as_slice()).unwrap();
67-
let en_passant_target =
68-
Square::try_from_fen_repr(fen.en_passant_target_square.as_slice()).unwrap();
69-
let full_move_count =
70-
FullMoveCount::try_from_fen_repr(fen.full_move_number.as_slice()).unwrap();
73+
let active_player = PlayerKind::try_from_fen_repr(fen.active_player.as_slice())
74+
.map_err(GameFromFenError::MalformedPlayer)?;
75+
76+
let en_passant_target = Square::try_from_fen_repr(fen.en_passant_target_square.as_slice())
77+
.map_err(GameFromFenError::MalformedEnPassantTarget)?;
78+
79+
let full_move_count = FullMoveCount::try_from_fen_repr(fen.full_move_number.as_slice())
80+
.map_err(GameFromFenError::MalformedMoveCount)?;
7181

7282
Ok(Self {
7383
board,
@@ -161,7 +171,11 @@ impl FullMoveCount {
161171
}
162172

163173
fn to_fen_repr(self) -> Vec<AsciiChar> {
164-
self.0.to_string().as_ascii().unwrap().to_owned()
174+
self.0
175+
.to_string()
176+
.as_ascii()
177+
.expect("digits are ascii")
178+
.to_owned()
165179
}
166180
}
167181

@@ -171,7 +185,11 @@ impl FiftyMoveRuleClock {
171185
}
172186

173187
fn to_fen_repr(self) -> Vec<AsciiChar> {
174-
self.0.to_string().as_ascii().unwrap().to_owned()
188+
self.0
189+
.to_string()
190+
.as_ascii()
191+
.expect("digits are ascii")
192+
.to_owned()
175193
}
176194
}
177195

@@ -269,24 +287,20 @@ pub enum BoardFromFenError {
269287

270288
impl Board {
271289
fn try_from_fen_repr(value: &[AsciiChar]) -> Result<Self, BoardFromFenError> {
272-
fn ascii_char_digit_to_int(char: AsciiChar) -> usize {
273-
match char as u8 {
274-
..=b'0' => panic!("{char} is an unexpectedly low digit / ascii char"),
275-
b'1'..=b'8' => usize::from(u8::from(char) - b'0'),
276-
b'9'.. => panic!("{char} is an unexpectedly high digit / ascii char"),
277-
}
278-
}
279290
fn fen_row_to_board_row(
280291
row: &[AsciiChar],
281292
) -> Result<[Option<Piece>; 8], BoardFromFenError> {
282293
let mut out_row: Vec<Option<Piece>> = vec![];
283294

284295
for c in row {
285296
match *c as u8 {
286-
b'1'..=b'8' => out_row.extend(vec![None; ascii_char_digit_to_int(*c)]),
297+
b'1'..=b'8' => out_row.extend(vec![None; usize::from(u8::from(*c) - b'0')]),
287298
b'P' | b'N' | b'B' | b'R' | b'Q' | b'K' | b'p' | b'n' | b'b' | b'r' | b'q'
288299
| b'k' => {
289-
out_row.push(Some(Piece::try_from_fen_repr(*c).unwrap()));
300+
out_row.push(Some(
301+
Piece::try_from_fen_repr(*c)
302+
.expect("these chars are valid Piece reprs"),
303+
));
290304
}
291305

292306
_ => return Err(BoardFromFenError::IllegalCharacter(*c)),
@@ -311,8 +325,9 @@ impl Board {
311325
//TODO: un-fuck this
312326
for square in Square::ALL {
313327
new_board[Square {
314-
col: Col::try_from(u8::from(square.row)).unwrap(),
315-
row: Row::try_from(9 - u8::from(square.col)).unwrap(),
328+
col: Col::try_from(u8::from(square.row))
329+
.expect("valid row numbers are valid col numbers"),
330+
row: Row::try_from(9 - u8::from(square.col)).expect("9 - 1..=8 is in range 1..=8"),
316331
}] = piece_placements_chunked[square];
317332
}
318333

@@ -332,7 +347,7 @@ impl Board {
332347
running_square_count
333348
.to_string()
334349
.as_ascii()
335-
.unwrap()
350+
.expect("digits are ascii")
336351
.to_owned(),
337352
); //as the running count should never exceed 8, this should always be a single digit
338353
}
@@ -346,7 +361,7 @@ impl Board {
346361
running_square_count
347362
.to_string()
348363
.as_ascii()
349-
.unwrap()
364+
.expect("digits are ascii")
350365
.to_owned(),
351366
); //as the running count should never exceed 8, this should always be a single digit
352367
}
@@ -366,7 +381,7 @@ impl Col {
366381
}
367382
#[must_use]
368383
pub(crate) const fn to_fen_repr(self) -> AsciiChar {
369-
AsciiChar::from_u8(u8::from(self) + b'a' - 1).unwrap()
384+
AsciiChar::from_u8(u8::from(self) + b'a' - 1).expect("a..=h are ascii")
370385
}
371386
}
372387
impl Row {
@@ -375,7 +390,7 @@ impl Row {
375390
}
376391
#[must_use]
377392
pub(crate) const fn to_fen_repr(self) -> AsciiChar {
378-
AsciiChar::from_u8(u8::from(self) + b'0').unwrap()
393+
AsciiChar::from_u8(u8::from(self) + b'0').expect("0..=8 are ascii")
379394
}
380395
}
381396

@@ -467,7 +482,7 @@ mod tests {
467482

468483
#[test]
469484
fn test_player_kind_fens_round_trip() {
470-
for player_kind in [PlayerKind::White, PlayerKind::Black] {
485+
for player_kind in PlayerKind::ALL {
471486
println!(
472487
"{player_kind:?}: {}",
473488
PlayerKind::to_fen_repr(player_kind).as_str()

src/player.rs

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ pub enum PlayerKind {
1515
Black,
1616
}
1717
impl PlayerKind {
18+
pub const ALL: [Self; 2] = [Self::White, Self::Black];
19+
1820
#[must_use]
1921
pub const fn opponent(self) -> Self {
2022
match self {
@@ -24,23 +26,23 @@ impl PlayerKind {
2426
}
2527

2628
#[must_use]
27-
pub const fn pawn_starting_row(self) -> Row {
29+
pub(crate) const fn pawn_starting_row(self) -> Row {
2830
match self {
2931
Self::White => Row::_2,
3032
Self::Black => Row::_7,
3133
}
3234
}
3335

3436
#[must_use]
35-
pub const fn pawn_promotion_row(self) -> Row {
37+
pub(crate) const fn pawn_promotion_row(self) -> Row {
3638
match self {
3739
Self::White => Row::_8,
3840
Self::Black => Row::_1,
3941
}
4042
}
4143

4244
#[must_use]
43-
pub const fn castling_non_check_needed_squares(self, castling_side: CS) -> [Square; 3] {
45+
pub(crate) const fn castling_non_check_needed_squares(self, castling_side: CS) -> [Square; 3] {
4446
match (self, castling_side) {
4547
(Self::White, CS::Kingside) => [S::E1, S::F1, S::G1],
4648
(Self::White, CS::Queenside) => [S::E1, S::D1, S::C1],
@@ -50,7 +52,7 @@ impl PlayerKind {
5052
}
5153

5254
#[must_use]
53-
pub fn castling_free_needed_squares(self, castling_side: CS) -> Vec<Square> {
55+
pub(crate) fn castling_free_needed_squares(self, castling_side: CS) -> Vec<Square> {
5456
match (self, castling_side) {
5557
(Self::White, CS::Kingside) => vec![S::F1, S::G1],
5658
(Self::White, CS::Queenside) => {
@@ -64,15 +66,15 @@ impl PlayerKind {
6466
}
6567

6668
#[must_use]
67-
pub const fn king_start(&self) -> Square {
69+
pub(crate) const fn king_start(self) -> Square {
6870
match self {
6971
Self::White => S::E1,
7072
Self::Black => S::E8,
7173
}
7274
}
7375

7476
#[must_use]
75-
pub const fn king_castling_target(&self, castling_side: CS) -> Square {
77+
pub(crate) const fn king_castling_target(self, castling_side: CS) -> Square {
7678
match (self, castling_side) {
7779
(Self::White, CS::Kingside) => S::G1,
7880
(Self::White, CS::Queenside) => S::C1,
@@ -82,7 +84,7 @@ impl PlayerKind {
8284
}
8385

8486
#[must_use]
85-
pub const fn rook_start(&self, castling_side: CS) -> Square {
87+
pub(crate) const fn rook_start(self, castling_side: CS) -> Square {
8688
match (self, castling_side) {
8789
(Self::White, CS::Kingside) => S::H1,
8890
(Self::White, CS::Queenside) => S::A1,
@@ -92,7 +94,7 @@ impl PlayerKind {
9294
}
9395

9496
#[must_use]
95-
pub const fn rook_castling_target(&self, castling_side: CS) -> Square {
97+
pub const fn rook_castling_target(self, castling_side: CS) -> Square {
9698
match (self, castling_side) {
9799
(Self::White, CS::Kingside) => S::F1,
98100
(Self::White, CS::Queenside) => S::D1,
@@ -102,15 +104,15 @@ impl PlayerKind {
102104
}
103105

104106
#[must_use]
105-
pub const fn forwards_one_row(&self) -> Offset {
107+
pub(crate) const fn forwards_one_row(self) -> Offset {
106108
match self {
107109
Self::White => Offset::U,
108110
Self::Black => Offset::D,
109111
}
110112
}
111113

112114
#[must_use]
113-
pub const fn backwards_one_row(&self) -> Offset {
115+
pub(crate) const fn backwards_one_row(self) -> Offset {
114116
self.forwards_one_row() * -1
115117
}
116118
}

0 commit comments

Comments
 (0)