1use std::borrow::Cow;
2use std::fmt;
3use std::fmt::Formatter;
4
5#[derive(Debug, PartialEq)]
7pub enum Error {
8 InvalidInput(String),
10 Eval(EvalError),
12}
13
14impl fmt::Display for Error {
15 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
16 use Error::*;
17 match self {
18 InvalidInput(msg) => write!(f, "invalid input: {}", msg),
19 Eval(err) => write!(f, "{}", err),
20 }
21 }
22}
23
24impl std::error::Error for Error {}
25
26#[derive(Debug)]
27pub(crate) struct InvalidOperatorError<'a> {
28 raw: Cow<'a, str>,
29}
30
31impl<'a> InvalidOperatorError<'a> {
32 pub(crate) fn new(op: impl Into<Cow<'a, str>>) -> Self {
33 InvalidOperatorError { raw: op.into() }
34 }
35}
36
37impl<'a> fmt::Display for InvalidOperatorError<'a> {
38 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
39 write!(
40 f,
41 "invalid operator '{}' currently ['+', '-', '*', '/'] supported",
42 self.raw
43 )
44 }
45}
46
47impl<'a> std::error::Error for InvalidOperatorError<'a> {}
48
49#[derive(Debug)]
50pub(crate) struct InvalidConstantError<'a> {
51 raw: Cow<'a, str>,
52}
53
54impl<'a> InvalidConstantError<'a> {
55 pub(crate) fn new(op: impl Into<Cow<'a, str>>) -> Self {
56 InvalidConstantError { raw: op.into() }
57 }
58}
59
60impl<'a> fmt::Display for InvalidConstantError<'a> {
61 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
62 write!(f, "invalid constant '{}'", self.raw)
63 }
64}
65
66impl<'a> std::error::Error for InvalidConstantError<'a> {}
67
68#[derive(Debug, PartialEq)]
70pub enum EvalError {
71 DivisionByZero,
74 UndefinedFunction {
77 ident: String,
79 },
80 ArgCountDoesNotMatch {
83 ident: &'static str,
85 expected: usize,
87 actual: usize,
89 },
90 VariableNotFound {
92 ident: String,
94 },
95}
96
97impl EvalError {
98 pub(crate) fn arg_count_does_not_match(
99 ident: &'static str,
100 expected: usize,
101 actual: usize,
102 ) -> Self {
103 EvalError::ArgCountDoesNotMatch {
104 ident,
105 expected,
106 actual,
107 }
108 }
109}
110
111impl fmt::Display for EvalError {
112 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
113 use EvalError::*;
114 match self {
115 DivisionByZero => write!(f, "divided by zero"),
116 UndefinedFunction { ident } => write!(f, "function '{ident}' undefined"),
117 ArgCountDoesNotMatch {
118 ident,
119 expected,
120 actual,
121 } => write!(
122 f,
123 "function '{ident}' arg count does not match. {actual} vs {expected}."
124 ),
125 VariableNotFound { ident } => write!(f, "variable '{ident}' not found"),
126 }
127 }
128}
129
130impl std::error::Error for EvalError {}