evalexpr/error/
mod.rs

1//! The `error` module contains the `Error` enum that contains all error types used by this crate.
2//!
3//! The `Error` enum implements constructors for its struct variants, because those are ugly to construct.
4//!
5//! The module also contains some helper functions starting with `expect_` that check for a condition and return `Err(_)` if the condition is not fulfilled.
6//! They are meant as shortcuts to not write the same error checking code everywhere.
7
8use std::ops::RangeInclusive;
9
10use crate::{
11    token::PartialToken,
12    value::{
13        numeric_types::{default_numeric_types::DefaultNumericTypes, EvalexprNumericTypes},
14        value_type::ValueType,
15    },
16};
17
18use crate::{operator::Operator, value::Value};
19
20// Exclude error display code from test coverage, as the code does not make sense to test.
21#[cfg(not(tarpaulin_include))]
22mod display;
23
24/// Errors used in this crate.
25#[derive(Debug, Clone, PartialEq)]
26#[non_exhaustive]
27pub enum EvalexprError<NumericTypes: EvalexprNumericTypes = DefaultNumericTypes> {
28    /// An operator was called with a wrong amount of arguments.
29    WrongOperatorArgumentAmount {
30        /// The expected amount of arguments.
31        expected: usize,
32        /// The actual amount of arguments.
33        actual: usize,
34    },
35
36    /// A function was called with a wrong amount of arguments.
37    WrongFunctionArgumentAmount {
38        /// The expected amount of arguments.
39        expected: RangeInclusive<usize>,
40        /// The actual amount of arguments.
41        actual: usize,
42    },
43
44    /// A string value was expected.
45    ExpectedString {
46        /// The actual value.
47        actual: Value<NumericTypes>,
48    },
49
50    /// An integer value was expected.
51    ExpectedInt {
52        /// The actual value.
53        actual: Value<NumericTypes>,
54    },
55
56    /// A float value was expected.
57    ExpectedFloat {
58        /// The actual value.
59        actual: Value<NumericTypes>,
60    },
61
62    /// A numeric value was expected.
63    /// Numeric values are the variants `Value::Int` and `Value::Float`.
64    ExpectedNumber {
65        /// The actual value.
66        actual: Value<NumericTypes>,
67    },
68
69    /// A numeric or string value was expected.
70    /// Numeric values are the variants `Value::Int` and `Value::Float`.
71    ExpectedNumberOrString {
72        /// The actual value.
73        actual: Value<NumericTypes>,
74    },
75
76    /// A boolean value was expected.
77    ExpectedBoolean {
78        /// The actual value.
79        actual: Value<NumericTypes>,
80    },
81
82    /// A tuple value was expected.
83    ExpectedTuple {
84        /// The actual value.
85        actual: Value<NumericTypes>,
86    },
87
88    /// A tuple value of a certain length was expected.
89    ExpectedFixedLengthTuple {
90        /// The expected length.
91        expected_length: usize,
92        /// The actual value.
93        actual: Value<NumericTypes>,
94    },
95
96    /// A tuple value of a certain length range was expected.
97    ExpectedRangedLengthTuple {
98        /// The expected length range.
99        expected_length: RangeInclusive<usize>,
100        /// The actual value.
101        actual: Value<NumericTypes>,
102    },
103
104    /// An empty value was expected.
105    ExpectedEmpty {
106        /// The actual value.
107        actual: Value<NumericTypes>,
108    },
109
110    /// Tried to append a child to a leaf node.
111    /// Leaf nodes cannot have children.
112    AppendedToLeafNode,
113
114    /// Tried to append a child to a node such that the precedence of the child is not higher.
115    /// This error should never occur.
116    /// If it does, please file a bug report.
117    PrecedenceViolation,
118
119    /// A `VariableIdentifier` operation did not find its value in the context.
120    VariableIdentifierNotFound(String),
121
122    /// A `FunctionIdentifier` operation did not find its value in the context.
123    FunctionIdentifierNotFound(String),
124
125    /// A value has the wrong type.
126    /// Only use this if there is no other error that describes the expected and provided types in more detail.
127    TypeError {
128        /// The expected types.
129        expected: Vec<ValueType>,
130        /// The actual value.
131        actual: Value<NumericTypes>,
132    },
133
134    /// An operator is used with a wrong combination of types.
135    WrongTypeCombination {
136        /// The operator that whose evaluation caused the error.
137        operator: Operator<NumericTypes>,
138        /// The types that were used in the operator causing it to fail.
139        actual: Vec<ValueType>,
140    },
141
142    /// An opening brace without a matching closing brace was found.
143    UnmatchedLBrace,
144
145    /// A closing brace without a matching opening brace was found.
146    UnmatchedRBrace,
147
148    /// A double quote without a matching second double quote was found.
149    UnmatchedDoubleQuote,
150
151    /// Left of an opening brace or right of a closing brace is a token that does not expect the brace next to it.
152    /// For example, writing `4(5)` would yield this error, as the `4` does not have any operands.
153    MissingOperatorOutsideOfBrace,
154
155    /// A `PartialToken` is unmatched, such that it cannot be combined into a full `Token`.
156    /// This happens if for example a single `=` is found, surrounded by whitespace.
157    /// It is not a token, but it is part of the string representation of some tokens.
158    UnmatchedPartialToken {
159        /// The unmatched partial token.
160        first: PartialToken<NumericTypes>,
161        /// The token that follows the unmatched partial token and that cannot be matched to the partial token, or `None`, if `first` is the last partial token in the stream.
162        second: Option<PartialToken<NumericTypes>>,
163    },
164
165    /// An addition operation performed by Rust failed.
166    AdditionError {
167        /// The first argument of the addition.
168        augend: Value<NumericTypes>,
169        /// The second argument of the addition.
170        addend: Value<NumericTypes>,
171    },
172
173    /// A subtraction operation performed by Rust failed.
174    SubtractionError {
175        /// The first argument of the subtraction.
176        minuend: Value<NumericTypes>,
177        /// The second argument of the subtraction.
178        subtrahend: Value<NumericTypes>,
179    },
180
181    /// A negation operation performed by Rust failed.
182    NegationError {
183        /// The argument of the negation.
184        argument: Value<NumericTypes>,
185    },
186
187    /// A multiplication operation performed by Rust failed.
188    MultiplicationError {
189        /// The first argument of the multiplication.
190        multiplicand: Value<NumericTypes>,
191        /// The second argument of the multiplication.
192        multiplier: Value<NumericTypes>,
193    },
194
195    /// A division operation performed by Rust failed.
196    DivisionError {
197        /// The first argument of the division.
198        dividend: Value<NumericTypes>,
199        /// The second argument of the division.
200        divisor: Value<NumericTypes>,
201    },
202
203    /// A modulation operation performed by Rust failed.
204    ModulationError {
205        /// The first argument of the modulation.
206        dividend: Value<NumericTypes>,
207        /// The second argument of the modulation.
208        divisor: Value<NumericTypes>,
209    },
210
211    /// A regular expression could not be parsed
212    InvalidRegex {
213        /// The invalid regular expression
214        regex: String,
215        /// Failure message from the regex engine
216        message: String,
217    },
218
219    /// A modification was attempted on a `Context` that does not allow modifications.
220    ContextNotMutable,
221
222    /// An escape sequence within a string literal is illegal.
223    IllegalEscapeSequence(String),
224
225    /// This context does not allow enabling builtin functions.
226    BuiltinFunctionsCannotBeEnabled,
227
228    /// This context does not allow disabling builtin functions.
229    BuiltinFunctionsCannotBeDisabled,
230
231    /// Out of bounds sequence access.
232    OutOfBoundsAccess,
233
234    /// A `usize` was attempted to be converted to an `int`, but it was out of range.
235    IntFromUsize {
236        /// The `usize` that was attempted to be converted.
237        usize_int: usize,
238    },
239
240    /// An `int` was attempted to be converted to a `usize`, but it was out of range.
241    IntIntoUsize {
242        /// The `int` that was attempted to be converted.
243        int: NumericTypes::Int,
244    },
245
246    /// The feature `rand` is not enabled, but required for the used function.
247    RandNotEnabled,
248
249    /// A custom error explained by its message.
250    CustomMessage(String),
251}
252
253impl<NumericTypes: EvalexprNumericTypes> EvalexprError<NumericTypes> {
254    /// Construct a `WrongOperatorArgumentAmount` error.
255    pub fn wrong_operator_argument_amount(actual: usize, expected: usize) -> Self {
256        EvalexprError::WrongOperatorArgumentAmount { actual, expected }
257    }
258
259    /// Construct a `WrongFunctionArgumentAmount` error for a function with a fixed amount of arguments.
260    pub fn wrong_function_argument_amount(actual: usize, expected: usize) -> Self {
261        EvalexprError::WrongFunctionArgumentAmount {
262            actual,
263            expected: expected..=expected,
264        }
265    }
266
267    /// Construct a `WrongFunctionArgumentAmount` error for a function with a range of possible amounts of arguments.
268    pub fn wrong_function_argument_amount_range(
269        actual: usize,
270        expected: RangeInclusive<usize>,
271    ) -> Self {
272        EvalexprError::WrongFunctionArgumentAmount { actual, expected }
273    }
274
275    /// Constructs `EvalexprError::TypeError{actual, expected}`.
276    pub fn type_error(actual: Value<NumericTypes>, expected: Vec<ValueType>) -> Self {
277        EvalexprError::TypeError { actual, expected }
278    }
279
280    /// Constructs `EvalexprError::WrongTypeCombination{operator, actual}`.
281    pub fn wrong_type_combination(
282        operator: Operator<NumericTypes>,
283        actual: Vec<ValueType>,
284    ) -> Self {
285        EvalexprError::WrongTypeCombination { operator, actual }
286    }
287
288    /// Constructs `EvalexprError::ExpectedString{actual}`.
289    pub fn expected_string(actual: Value<NumericTypes>) -> Self {
290        EvalexprError::ExpectedString { actual }
291    }
292
293    /// Constructs `EvalexprError::ExpectedInt{actual}`.
294    pub fn expected_int(actual: Value<NumericTypes>) -> Self {
295        EvalexprError::ExpectedInt { actual }
296    }
297
298    /// Constructs `EvalexprError::ExpectedFloat{actual}`.
299    pub fn expected_float(actual: Value<NumericTypes>) -> Self {
300        EvalexprError::ExpectedFloat { actual }
301    }
302
303    /// Constructs `EvalexprError::ExpectedNumber{actual}`.
304    pub fn expected_number(actual: Value<NumericTypes>) -> Self {
305        EvalexprError::ExpectedNumber { actual }
306    }
307
308    /// Constructs `EvalexprError::ExpectedNumberOrString{actual}`.
309    pub fn expected_number_or_string(actual: Value<NumericTypes>) -> Self {
310        EvalexprError::ExpectedNumberOrString { actual }
311    }
312
313    /// Constructs `EvalexprError::ExpectedBoolean{actual}`.
314    pub fn expected_boolean(actual: Value<NumericTypes>) -> Self {
315        EvalexprError::ExpectedBoolean { actual }
316    }
317
318    /// Constructs `EvalexprError::ExpectedTuple{actual}`.
319    pub fn expected_tuple(actual: Value<NumericTypes>) -> Self {
320        EvalexprError::ExpectedTuple { actual }
321    }
322
323    /// Constructs `EvalexprError::ExpectedFixedLenTuple{expected_len, actual}`.
324    pub fn expected_fixed_len_tuple(expected_len: usize, actual: Value<NumericTypes>) -> Self {
325        EvalexprError::ExpectedFixedLengthTuple {
326            expected_length: expected_len,
327            actual,
328        }
329    }
330
331    /// Constructs `EvalexprError::ExpectedFixedLenTuple{expected_len, actual}`.
332    pub fn expected_ranged_len_tuple(
333        expected_len: RangeInclusive<usize>,
334        actual: Value<NumericTypes>,
335    ) -> Self {
336        EvalexprError::ExpectedRangedLengthTuple {
337            expected_length: expected_len,
338            actual,
339        }
340    }
341
342    /// Constructs `EvalexprError::ExpectedEmpty{actual}`.
343    pub fn expected_empty(actual: Value<NumericTypes>) -> Self {
344        EvalexprError::ExpectedEmpty { actual }
345    }
346
347    /// Constructs an error that expresses that the type of `expected` was expected, but `actual` was found.
348    pub(crate) fn expected_type(
349        expected: &Value<NumericTypes>,
350        actual: Value<NumericTypes>,
351    ) -> Self {
352        match ValueType::from(expected) {
353            ValueType::String => Self::expected_string(actual),
354            ValueType::Int => Self::expected_int(actual),
355            ValueType::Float => Self::expected_float(actual),
356            ValueType::Boolean => Self::expected_boolean(actual),
357            ValueType::Tuple => Self::expected_tuple(actual),
358            ValueType::Empty => Self::expected_empty(actual),
359        }
360    }
361
362    pub(crate) fn unmatched_partial_token(
363        first: PartialToken<NumericTypes>,
364        second: Option<PartialToken<NumericTypes>>,
365    ) -> Self {
366        EvalexprError::UnmatchedPartialToken { first, second }
367    }
368
369    pub(crate) fn addition_error(augend: Value<NumericTypes>, addend: Value<NumericTypes>) -> Self {
370        EvalexprError::AdditionError { augend, addend }
371    }
372
373    pub(crate) fn subtraction_error(
374        minuend: Value<NumericTypes>,
375        subtrahend: Value<NumericTypes>,
376    ) -> Self {
377        EvalexprError::SubtractionError {
378            minuend,
379            subtrahend,
380        }
381    }
382
383    pub(crate) fn negation_error(argument: Value<NumericTypes>) -> Self {
384        EvalexprError::NegationError { argument }
385    }
386
387    pub(crate) fn multiplication_error(
388        multiplicand: Value<NumericTypes>,
389        multiplier: Value<NumericTypes>,
390    ) -> Self {
391        EvalexprError::MultiplicationError {
392            multiplicand,
393            multiplier,
394        }
395    }
396
397    pub(crate) fn division_error(
398        dividend: Value<NumericTypes>,
399        divisor: Value<NumericTypes>,
400    ) -> Self {
401        EvalexprError::DivisionError { dividend, divisor }
402    }
403
404    pub(crate) fn modulation_error(
405        dividend: Value<NumericTypes>,
406        divisor: Value<NumericTypes>,
407    ) -> Self {
408        EvalexprError::ModulationError { dividend, divisor }
409    }
410
411    /// Constructs `EvalexprError::InvalidRegex(regex)`
412    pub fn invalid_regex(regex: String, message: String) -> Self {
413        EvalexprError::InvalidRegex { regex, message }
414    }
415}
416
417/// Returns `Ok(())` if the actual and expected parameters are equal, and `Err(Error::WrongOperatorArgumentAmount)` otherwise.
418pub(crate) fn expect_operator_argument_amount<NumericTypes: EvalexprNumericTypes>(
419    actual: usize,
420    expected: usize,
421) -> EvalexprResult<(), NumericTypes> {
422    if actual == expected {
423        Ok(())
424    } else {
425        Err(EvalexprError::wrong_operator_argument_amount(
426            actual, expected,
427        ))
428    }
429}
430
431/// Returns `Ok(())` if the actual and expected parameters are equal, and `Err(Error::WrongFunctionArgumentAmount)` otherwise.
432pub fn expect_function_argument_amount<NumericTypes: EvalexprNumericTypes>(
433    actual: usize,
434    expected: usize,
435) -> EvalexprResult<(), NumericTypes> {
436    if actual == expected {
437        Ok(())
438    } else {
439        Err(EvalexprError::wrong_function_argument_amount(
440            actual, expected,
441        ))
442    }
443}
444
445/// Returns `Ok(())` if the given value is a string or a numeric
446pub fn expect_number_or_string<NumericTypes: EvalexprNumericTypes>(
447    actual: &Value<NumericTypes>,
448) -> EvalexprResult<(), NumericTypes> {
449    match actual {
450        Value::String(_) | Value::Float(_) | Value::Int(_) => Ok(()),
451        _ => Err(EvalexprError::expected_number_or_string(actual.clone())),
452    }
453}
454
455impl<NumericTypes: EvalexprNumericTypes> std::error::Error for EvalexprError<NumericTypes> {}
456
457/// Standard result type used by this crate.
458pub type EvalexprResult<T, NumericTypes = DefaultNumericTypes> =
459    Result<T, EvalexprError<NumericTypes>>;
460
461/// Standard result type for [`Value`]s used by this crate.
462pub type EvalexprResultValue<NumericTypes = DefaultNumericTypes> =
463    EvalexprResult<Value<NumericTypes>, NumericTypes>;
464
465#[cfg(test)]
466mod tests {
467    use crate::{
468        value::numeric_types::default_numeric_types::DefaultNumericTypes, EvalexprError, Value,
469        ValueType,
470    };
471
472    /// Tests whose only use is to bring test coverage of trivial lines up, like trivial constructors.
473    #[test]
474    fn trivial_coverage_tests() {
475        assert_eq!(
476            EvalexprError::type_error(
477                Value::<DefaultNumericTypes>::Int(3),
478                vec![ValueType::String]
479            ),
480            EvalexprError::TypeError {
481                actual: Value::Int(3),
482                expected: vec![ValueType::String]
483            }
484        );
485        assert_eq!(
486            EvalexprError::expected_type(
487                &Value::<DefaultNumericTypes>::String("abc".to_string()),
488                Value::Empty
489            ),
490            EvalexprError::expected_string(Value::Empty)
491        );
492        assert_eq!(
493            EvalexprError::expected_type(
494                &Value::<DefaultNumericTypes>::Boolean(false),
495                Value::Empty
496            ),
497            EvalexprError::expected_boolean(Value::Empty)
498        );
499        assert_eq!(
500            EvalexprError::expected_type(
501                &Value::<DefaultNumericTypes>::Tuple(vec![]),
502                Value::Empty
503            ),
504            EvalexprError::expected_tuple(Value::Empty)
505        );
506        assert_eq!(
507            EvalexprError::expected_type(
508                &Value::<DefaultNumericTypes>::Empty,
509                Value::String("abc".to_string())
510            ),
511            EvalexprError::expected_empty(Value::String("abc".to_string()))
512        );
513    }
514}