use core::fmt;
#[derive(Debug, Clone, Copy)]
pub(crate) struct Error {
at: usize,
kind: ErrorKind,
}
impl Error {
#[inline]
pub(crate) const fn new(at: usize, kind: ErrorKind) -> Self {
Self { at, kind }
}
#[inline]
pub(crate) const fn at(&self) -> usize {
self.at
}
}
impl fmt::Display for Error {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
self.kind.fmt(f)
}
}
#[cfg(feature = "std")]
impl std::error::Error for Error {}
#[derive(Debug, Clone, Copy)]
pub(crate) enum Expected {
Number,
Fraction,
Exponent,
Hex,
}
impl fmt::Display for Expected {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Expected::Number => write!(f, "a digit"),
Expected::Fraction => write!(f, "a digit in the fraction"),
Expected::Exponent => write!(f, "a digit in the exponent"),
Expected::Hex => write!(f, "a hexadecimal digit"),
}
}
}
#[derive(Debug, Clone, Copy)]
#[non_exhaustive]
pub(crate) enum ErrorKind {
Eof(Expected),
Unexpected(Expected, u8),
LeadingZero,
Overflow,
ExponentOverflow,
Fraction,
Float,
}
impl fmt::Display for ErrorKind {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
ErrorKind::Eof(expected) => {
write!(f, "Expected {expected}, but the number ended")
}
ErrorKind::Unexpected(expected, b) => {
write!(f, "Expected {expected}, but found ")?;
Byte(*b).fmt(f)
}
ErrorKind::LeadingZero => {
write!(f, "A number must not have a redundant leading zero")
}
ErrorKind::Overflow => write!(f, "Arithmetic overflow"),
ErrorKind::ExponentOverflow => write!(f, "Exponent is out of range"),
ErrorKind::Fraction => write!(f, "Expected a whole number, but found a fraction"),
ErrorKind::Float => write!(f, "Illegal float encountered"),
}
}
}
struct Byte(u8);
impl fmt::Display for Byte {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self.0 {
b'\x20'..=b'\x7e' => write!(f, "`{}`", self.0 as char),
b => write!(f, "byte {b:#04x}"),
}
}
}