use core::fmt;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct Span {
pub start: usize,
pub end: usize,
}
impl Span {
pub const fn new(start: usize, end: usize) -> Self {
Self { start, end }
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
#[non_exhaustive]
pub enum ErrorKind {
UnexpectedCharacter,
UnexpectedToken,
UnexpectedEnd,
UnclosedParenthesis,
InvalidNumber,
UnknownVariable,
UnknownFunction,
TooManyArguments,
ArgumentCount,
DivisionByZero,
Domain,
Overflow,
TooDeep,
Unsupported,
TooLong,
Inexact,
}
impl ErrorKind {
pub const fn description(self) -> &'static str {
match self {
Self::UnexpectedCharacter => "unexpected character",
Self::UnexpectedToken => "unexpected token",
Self::UnexpectedEnd => "unexpected end of expression",
Self::UnclosedParenthesis => "unclosed parenthesis",
Self::InvalidNumber => "invalid number",
Self::UnknownVariable => "unknown variable",
Self::UnknownFunction => "unknown function",
Self::TooManyArguments => "too many arguments",
Self::ArgumentCount => "wrong number of arguments",
Self::DivisionByZero => "division by zero",
Self::Domain => "operand out of domain",
Self::Overflow => "overflow",
Self::TooDeep => "expression nested too deeply",
Self::Unsupported => "unsupported operation",
Self::TooLong => "expression too long",
Self::Inexact => "inexact result",
}
}
}
impl fmt::Display for ErrorKind {
fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
formatter.write_str(self.description())
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct Error {
pub kind: ErrorKind,
pub span: Span,
}
impl Error {
pub const fn new(kind: ErrorKind, span: Span) -> Self {
Self { kind, span }
}
}
impl fmt::Display for Error {
fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(
formatter,
"{} at {}..{}",
self.kind, self.span.start, self.span.end
)
}
}
impl core::error::Error for Error {}