1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
use super::Lookup;
use enum_dispatch::enum_dispatch;
use std::error::Error;
use std::fmt;
use std::io::Error as IOError;
#[derive(Debug)]
pub enum CastError {
IncompatibleCast {
from: &'static str,
to: &'static str,
},
NumParseError(<f64 as std::str::FromStr>::Err),
RegexError(regex::Error),
}
impl Error for CastError {}
impl fmt::Display for CastError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
Self::IncompatibleCast { from, to } => write!(f, "can't cast {} to {}", from, to),
Self::RegexError(err) => write!(f, "couldn't parse regex: {}", err),
Self::NumParseError(err) => write!(f, "error at parsing number: {}", err),
}
}
}
#[enum_dispatch]
trait Error1: Error {}
#[enum_dispatch(Error1)]
#[derive(Debug)]
pub enum ErrorKind {
IOError,
LookupError,
CastError,
ArgCountMismatched,
}
impl Error for ErrorKind {
fn source(&self) -> Option<&(dyn Error + 'static)> {
Some(match self {
Self::IOError(err) => err,
Self::LookupError(err) => err,
Self::CastError(err) => err,
Self::ArgCountMismatched(err) => err,
})
}
}
impl fmt::Display for ErrorKind {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}", self.source().unwrap())
}
}
#[derive(Debug)]
pub struct LookupError {
lookup: Lookup,
}
impl LookupError {
pub const fn new(lookup: Lookup) -> Self {
Self { lookup }
}
}
impl Error for LookupError {}
impl fmt::Display for LookupError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "Lookup {} has no initializer", self.lookup)
}
}
use crate::ast::Function;
#[derive(Debug)]
pub struct ArgCountMismatched {
function: Function,
got: usize,
}
impl ArgCountMismatched {
pub const fn new(function: Function, got: usize) -> Self {
Self { function, got }
}
pub const fn check(function: Function, arg_count: usize) -> Result<(), Self> {
if arg_count < function.minimum_arg_count() as usize {
Err(Self::new(function, arg_count))
} else {
Ok(())
}
}
}
impl Error for ArgCountMismatched {}
impl fmt::Display for ArgCountMismatched {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{function} expected at least {expected_count} arguments, but received {actual_count} instead", function = self.function, expected_count = self.function.minimum_arg_count(), actual_count = self.got)
}
}