use std::io;
use std::fmt;
use std::error::Error;
use shakmaty::Material;
use crate::types::Metric;
pub type SyzygyResult<T> = Result<T, SyzygyError>;
pub type ProbeResult<T> = Result<T, ProbeError>;
#[derive(Debug)]
pub enum SyzygyError {
Castling,
TooManyPieces,
MissingTable {
metric: Metric,
material: Material
},
ProbeFailed {
metric: Metric,
material: Material,
error: ProbeError,
},
}
impl fmt::Display for SyzygyError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
SyzygyError::Castling =>
write!(f, "syzygy tables do not contain position with castling rights"),
SyzygyError::TooManyPieces =>
write!(f, "too many pieces"),
SyzygyError::MissingTable { metric, material } =>
write!(f, "required {} table not found: {}", metric, material),
SyzygyError::ProbeFailed { metric, material, error } =>
write!(f, "failed to probe {} table {}: {}", metric, material, error),
}
}
}
impl Error for SyzygyError {
fn source(&self) -> Option<&(dyn Error + 'static)> {
match self {
SyzygyError::ProbeFailed { error, .. } => Some(error),
_ => None,
}
}
}
#[derive(Debug)]
pub enum ProbeError {
Read { error: io::Error },
Magic { magic: [u8; 4] },
CorruptedTable {
#[cfg(feature = "backtrace")]
backtrace: std::backtrace::Backtrace
},
}
impl fmt::Display for ProbeError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
ProbeError::Read { error } =>
write!(f, "i/o error reading table file: {}", error),
ProbeError::Magic { magic } =>
write!(f, "invalid magic header bytes: {:x?}", magic),
ProbeError::CorruptedTable { .. } =>
write!(f, "corrupted table"),
}
}
}
impl Error for ProbeError {
fn source(&self) -> Option<&(dyn Error + 'static)> {
match self {
ProbeError::Read { error } => Some(error),
_ => None,
}
}
#[cfg(feature = "backtrace")]
fn backtrace(&self) -> Option<&std::backtrace::Backtrace> {
match self {
ProbeError::CorruptedTable { backtrace } => Some(backtrace),
_ => None
}
}
}
pub trait ProbeResultExt<T> {
fn ctx(self, metric: Metric, material: &Material) -> SyzygyResult<T>;
}
impl<T> ProbeResultExt<T> for ProbeResult<T> {
fn ctx(self, metric: Metric, material: &Material) -> SyzygyResult<T> {
self.map_err(|error| SyzygyError::ProbeFailed {
metric,
material: material.clone().into_normalized(),
error,
})
}
}
impl From<io::Error> for ProbeError {
fn from(error: io::Error) -> ProbeError {
match error.kind() {
io::ErrorKind::UnexpectedEof => ProbeError::CorruptedTable {
#[cfg(feature = "backtrace")]
backtrace: std::backtrace::Backtrace::capture()
},
_ => ProbeError::Read { error },
}
}
}
macro_rules! throw {
() => {
return Err(crate::errors::ProbeError::CorruptedTable {
#[cfg(feature = "backtrace")]
backtrace: ::std::backtrace::Backtrace::capture()
})
}
}
macro_rules! u {
($e:expr) => {
match $e {
Some(ok) => ok,
None => throw!(),
}
};
}
macro_rules! ensure {
($cond:expr) => {
if !$cond {
throw!();
}
};
}