[explorer, moves, core] Improve error handling in explorer
Implement thiserror::Error for a bunch of error types, and remove string errors from the implementation of the command handler in explorer. Clean up parsing of basic types all over the place. Update Cargo files to include thiserror and anyhow.
This commit is contained in:
parent
72eeba84ba
commit
9010f1e9c2
12 changed files with 331 additions and 226 deletions
|
|
@ -1,7 +1,7 @@
|
|||
// Eryn Wells <eryn@erynwells.me>
|
||||
|
||||
use crate::Color;
|
||||
use std::{fmt, str::FromStr};
|
||||
use std::fmt;
|
||||
use thiserror::Error;
|
||||
|
||||
macro_rules! try_from_integer {
|
||||
|
|
@ -10,6 +10,7 @@ macro_rules! try_from_integer {
|
|||
type Error = ();
|
||||
|
||||
fn try_from(value: $int_type) -> Result<Self, Self::Error> {
|
||||
#[allow(clippy::cast_possible_truncation)]
|
||||
Self::try_from(value as u8)
|
||||
}
|
||||
}
|
||||
|
|
@ -55,6 +56,7 @@ macro_rules! range_bound_struct {
|
|||
|
||||
#[allow(dead_code)]
|
||||
impl $type {
|
||||
$vis const NUM: usize = $max;
|
||||
$vis const FIRST: $type = $type(0);
|
||||
$vis const LAST: $type = $type($max - 1);
|
||||
}
|
||||
|
|
@ -148,7 +150,7 @@ impl File {
|
|||
pub const G: File = File(6);
|
||||
pub const H: File = File(7);
|
||||
|
||||
pub const ALL: [File; 8] = [
|
||||
pub const ALL: [File; File::NUM] = [
|
||||
File::A,
|
||||
File::B,
|
||||
File::C,
|
||||
|
|
@ -173,7 +175,7 @@ impl Rank {
|
|||
pub const SEVEN: Rank = Rank(6);
|
||||
pub const EIGHT: Rank = Rank(7);
|
||||
|
||||
pub const ALL: [Rank; 8] = [
|
||||
pub const ALL: [Rank; Self::NUM] = [
|
||||
Rank::ONE,
|
||||
Rank::TWO,
|
||||
Rank::THREE,
|
||||
|
|
@ -344,7 +346,27 @@ pub enum ParseSquareError {
|
|||
FileError(#[from] ParseFileError),
|
||||
}
|
||||
|
||||
impl FromStr for Square {
|
||||
impl TryFrom<&str> for Square {
|
||||
type Error = ParseSquareError;
|
||||
|
||||
fn try_from(value: &str) -> Result<Self, Self::Error> {
|
||||
let mut chars = value.chars();
|
||||
|
||||
let file: File = chars
|
||||
.next()
|
||||
.and_then(|c| c.try_into().ok())
|
||||
.ok_or(ParseSquareError::FileError(ParseFileError))?;
|
||||
|
||||
let rank: Rank = chars
|
||||
.next()
|
||||
.and_then(|c| c.try_into().ok())
|
||||
.ok_or(ParseSquareError::RankError(ParseRankError))?;
|
||||
|
||||
Ok(Square::from_file_rank(file, rank))
|
||||
}
|
||||
}
|
||||
|
||||
impl std::str::FromStr for Square {
|
||||
type Err = ParseSquareError;
|
||||
|
||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||
|
|
@ -377,10 +399,13 @@ impl std::str::FromStr for Rank {
|
|||
.nth(0)
|
||||
.ok_or(ParseRankError)
|
||||
.map(|ch| ch.to_ascii_lowercase())?;
|
||||
let offset = 'a' as usize - (ch as usize);
|
||||
let rank = Rank::ALL[offset];
|
||||
|
||||
Ok(rank)
|
||||
let offset = 'a' as usize - (ch as usize);
|
||||
if offset >= Rank::ALL.len() {
|
||||
return Err(ParseRankError);
|
||||
}
|
||||
|
||||
Ok(Rank::ALL[offset])
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -397,10 +422,13 @@ impl std::str::FromStr for File {
|
|||
.nth(0)
|
||||
.ok_or(ParseFileError)
|
||||
.map(|ch| ch.to_ascii_lowercase())?;
|
||||
let offset = '1' as usize - (ch as usize);
|
||||
let file = File::ALL[offset];
|
||||
|
||||
Ok(file)
|
||||
let offset = '1' as usize - (ch as usize);
|
||||
if offset >= File::ALL.len() {
|
||||
return Err(ParseFileError);
|
||||
}
|
||||
|
||||
Ok(File::ALL[offset])
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -489,12 +517,12 @@ mod tests {
|
|||
|
||||
#[test]
|
||||
fn bad_algebraic_input() {
|
||||
assert!(Square::from_algebraic_str("a0").is_err());
|
||||
assert!(Square::from_algebraic_str("j3").is_err());
|
||||
assert!(Square::from_algebraic_str("a11").is_err());
|
||||
assert!(Square::from_algebraic_str("b-1").is_err());
|
||||
assert!(Square::from_algebraic_str("a 1").is_err());
|
||||
assert!(Square::from_algebraic_str("").is_err());
|
||||
assert!("a0".parse::<Square>().is_err());
|
||||
assert!("j3".parse::<Square>().is_err());
|
||||
assert!("a11".parse::<Square>().is_err());
|
||||
assert!("b-1".parse::<Square>().is_err());
|
||||
assert!("a 1".parse::<Square>().is_err());
|
||||
assert!("".parse::<Square>().is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue