use core::fmt;
#[derive(Clone, Debug, PartialEq, Eq)]
#[non_exhaustive]
pub enum Error {
StepLimit {
limit: u64,
},
InvalidPattern {
arm: usize,
node: usize,
reason: Reason,
},
Model {
reason: &'static str,
},
TooLarge,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
#[non_exhaustive]
pub enum Reason {
Kind,
Variant {
index: u32,
count: u32,
},
Fields {
expected: usize,
found: usize,
},
EmptyRange,
OutOfDomain,
Length {
expected: u32,
found: usize,
},
}
impl fmt::Display for Error {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Error::StepLimit { limit } => {
write!(
f,
"match too complex to check: exceeded the step limit of {limit}"
)
}
Error::InvalidPattern { arm, node, reason } => {
write!(f, "arm {arm}, pattern node {node}: {reason}")
}
Error::Model { reason } => write!(f, "inconsistent constructor model: {reason}"),
Error::TooLarge => f.write_str("match too large: more than u32::MAX - 1 nodes"),
}
}
}
impl fmt::Display for Reason {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Reason::Kind => f.write_str("pattern does not fit the type"),
Reason::Variant { index, count } => {
write!(f, "variant {index} does not exist (the type has {count})")
}
Reason::Fields { expected, found } => {
write!(f, "expected {expected} fields, found {found}")
}
Reason::EmptyRange => f.write_str("range is empty (low end above high end)"),
Reason::OutOfDomain => f.write_str("value outside the type's bounds"),
Reason::Length { expected, found } => {
write!(
f,
"array of length {expected} cannot match a pattern of {found} elements"
)
}
}
}
}
impl core::error::Error for Error {}
#[cfg(test)]
mod tests {
use alloc::string::ToString;
use super::*;
#[test]
fn test_error_messages_name_the_problem() {
assert!(
Error::StepLimit { limit: 5 }
.to_string()
.contains("step limit of 5")
);
assert_eq!(
Error::InvalidPattern {
arm: 1,
node: 2,
reason: Reason::Kind
}
.to_string(),
"arm 1, pattern node 2: pattern does not fit the type"
);
assert!(Error::Model { reason: "x" }.to_string().ends_with(": x"));
assert!(Error::TooLarge.to_string().contains("too large"));
assert!(
Reason::Variant { index: 3, count: 2 }
.to_string()
.contains("variant 3")
);
assert!(Reason::EmptyRange.to_string().contains("empty"));
assert!(Reason::OutOfDomain.to_string().contains("bounds"));
assert!(
Reason::Length {
expected: 2,
found: 3
}
.to_string()
.contains("length 2")
);
}
}