use std::fmt;
#[derive(PartialEq, Eq)]
pub enum QuantorError {
PredicateFailed {
kind: QuantorKind,
index: usize
},
EmptyInput {
kind: QuantorKind
},
NoMatch {
kind: QuantorKind
},
UnexpectedMatch {
kind: QuantorKind,
index: usize
},
NotAllEqual {
kind: QuantorKind,
index: usize
},
PairwiseFailed {
kind: QuantorKind,
index: usize
},
ForAllExistsFailed {
kind: QuantorKind,
outer_index: usize
},
ExistsForAllFailed {
kind: QuantorKind,
outer_index: usize
},
ExactlyNFailed {
kind: QuantorKind,
found: usize,
expected: usize,
},
Custom(&'static str),
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum QuantorKind {
Forall,
Exists,
None,
ExactlyOne,
ExactlyN,
AllEqual,
Pairwise,
ForAllExists,
ExistsForAll,
Custom,
}
pub trait QuantorResultExt {
fn failing_index(&self) -> Option<usize>;
fn match_count(&self) -> Option<usize>;
}
impl fmt::Display for QuantorError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
use QuantorError::*;
match self {
PredicateFailed { kind, index } => write!(f, "Predicate failed for element at index {} of quantifier {}.", index, kind),
EmptyInput { kind } => write!(f, "Empty input for quantifier {}.", kind),
NoMatch { kind } => write!(f, "No element satisfied the predicate for quantifier {}.", kind),
UnexpectedMatch { kind, index } => write!(f, "Unexpected match found at index {} of quantifier {}.", index, kind),
NotAllEqual { kind, index } => write!(f, "Element at index {} of quantifier {} does not match the first element.", index, kind),
PairwiseFailed { kind, index } => write!(f, "Predicate failed for adjacent pair starting at index {} for quantifier {}.", index, kind),
ForAllExistsFailed { kind, outer_index } => write!(f, "Element at index {} in the outer collection failed to match any right-hand value for quantifier {}.", outer_index, kind),
ExistsForAllFailed { kind, outer_index } => write!(f, "Element at index {} in the left-hand collection failed the universal condition for quantifier {}.", outer_index, kind),
ExactlyNFailed { kind, found, expected } => write!(f, "Expected {} elements to match, found {} for quantifier {}.", expected, found, kind),
Custom(msg) => write!(f, "{}", msg),
}
}
}
impl fmt::Display for QuantorKind {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let name = match self {
QuantorKind::Forall => "forall",
QuantorKind::Exists => "exists",
QuantorKind::None => "none",
QuantorKind::ExactlyOne => "exactly_one",
QuantorKind::Pairwise => "pairwise",
QuantorKind::ExactlyN => "exactly_n",
QuantorKind::AllEqual => "all_equal",
QuantorKind::ForAllExists => "forallexists",
QuantorKind::ExistsForAll => "existsforall",
QuantorKind::Custom => "custom",
};
write!(f, "{}", name)
}
}
impl QuantorError {
#[inline]
#[must_use]
pub fn is_predicate_failed(&self) -> bool {
matches!(self, QuantorError::PredicateFailed {..})
}
#[inline]
#[must_use]
pub fn is_no_match(&self) -> bool {
matches!(self, QuantorError::NoMatch { .. })
}
#[inline]
#[must_use]
pub fn kind(&self) -> QuantorKind {
match self {
QuantorError::PredicateFailed { kind, .. } => *kind,
QuantorError::EmptyInput { kind } => *kind,
QuantorError::NoMatch { kind, .. } => *kind,
QuantorError::UnexpectedMatch { kind, .. } => *kind,
QuantorError::NotAllEqual { kind, .. } => *kind,
QuantorError::PairwiseFailed { kind, .. } => *kind,
QuantorError::ForAllExistsFailed { kind, .. } => *kind,
QuantorError::ExistsForAllFailed { kind, .. } => *kind,
QuantorError::ExactlyNFailed { kind, .. } => *kind,
QuantorError::Custom(_) => QuantorKind::Custom,
}
}
}
impl std::error::Error for QuantorError {}
impl From<&'static str> for QuantorError {
fn from(msg: &'static str) -> Self {
QuantorError::Custom(msg)
}
}
impl From<String> for QuantorError {
fn from(msg: String) -> Self {
QuantorError::Custom(Box::leak(msg.into_boxed_str()))
}
}
impl fmt::Debug for QuantorError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt::Display::fmt(self, f)
}
}
impl QuantorResultExt for Result<(), QuantorError> {
#[inline]
fn failing_index(&self) -> Option<usize> {
match self {
Err(QuantorError::PredicateFailed { index, .. }) => Some(*index),
Err(QuantorError::UnexpectedMatch { index, .. }) => Some(*index),
Err(QuantorError::PairwiseFailed { index, .. }) => Some(*index),
Err(QuantorError::ForAllExistsFailed { outer_index, .. }) => Some(*outer_index),
_ => None,
}
}
#[inline]
fn match_count(&self) -> Option<usize> {
match self {
Err(QuantorError::ExactlyNFailed { found, .. }) => Some(*found),
_ => None
}
}
}