2019-03-20 09:32:49 +00:00
//! The `error` module contains the `Error` enum that contains all error types used by this crate.
//!
//! The `Error` enum implements constructors for its struct variants, because those are ugly to construct.
//!
//! The module also contains some helper functions starting with `expect_` that check for a condition and return `Err(_)` if the condition is not fulfilled.
//! They are meant as shortcuts to not write the same error checking code everywhere.
2019-03-15 17:19:59 +00:00
use token ::PartialToken ;
2019-03-30 10:54:19 +00:00
use value ::{ value_type ::ValueType , TupleType } ;
2016-11-16 16:12:26 +00:00
2019-03-27 15:33:46 +00:00
use crate ::value ::Value ;
2019-03-23 12:27:44 +00:00
mod display ;
2019-03-20 09:32:49 +00:00
/// Errors used in this crate.
2019-03-15 15:11:31 +00:00
#[ derive(Debug, PartialEq) ]
2019-03-27 15:33:46 +00:00
pub enum EvalexprError {
2019-03-20 09:32:49 +00:00
/// An operator was called with a wrong amount of arguments.
2019-03-19 14:54:52 +00:00
WrongOperatorArgumentAmount {
2019-03-20 09:42:17 +00:00
/// The expected amount of arguments.
2019-03-19 14:54:52 +00:00
expected : usize ,
2019-03-20 09:42:17 +00:00
/// The actual amount of arguments.
2019-03-19 14:54:52 +00:00
actual : usize ,
} ,
2019-03-20 09:32:49 +00:00
/// A function was called with a wrong amount of arguments.
2019-03-19 14:54:52 +00:00
WrongFunctionArgumentAmount {
2019-03-20 09:42:17 +00:00
/// The expected amount of arguments.
2019-03-15 15:11:31 +00:00
expected : usize ,
2019-03-20 09:42:17 +00:00
/// The actual amount of arguments.
2019-03-15 15:11:31 +00:00
actual : usize ,
} ,
2019-03-20 09:32:49 +00:00
2019-03-20 14:29:50 +00:00
/// A string value was expected.
ExpectedString {
/// The actual value.
actual : Value ,
} ,
2019-03-20 09:42:17 +00:00
/// An integer value was expected.
ExpectedInt {
/// The actual value.
actual : Value ,
} ,
/// A float value was expected.
ExpectedFloat {
/// The actual value.
actual : Value ,
} ,
2019-03-20 09:32:49 +00:00
/// A numeric value was expected.
/// Numeric values are the variants `Value::Int` and `Value::Float`.
2019-03-15 15:11:31 +00:00
ExpectedNumber {
2019-03-20 09:42:17 +00:00
/// The actual value.
2019-03-15 15:11:31 +00:00
actual : Value ,
} ,
2019-03-20 09:32:49 +00:00
2019-04-05 21:07:54 +00:00
/// A numeric or string value was expected.
/// Numeric values are the variants `Value::Int` and `Value::Float`.
ExpectedNumberOrString {
/// The actual value.
actual : Value ,
} ,
2019-03-20 09:32:49 +00:00
/// A boolean value was expected.
2019-03-15 17:19:59 +00:00
ExpectedBoolean {
2019-03-20 09:42:17 +00:00
/// The actual value.
2019-03-15 17:19:59 +00:00
actual : Value ,
} ,
2016-11-16 16:12:26 +00:00
2019-03-20 14:29:50 +00:00
/// A tuple value was expected.
ExpectedTuple {
/// The actual value.
actual : Value ,
} ,
2019-03-28 08:56:30 +00:00
/// An empty value was expected.
ExpectedEmpty {
/// The actual value.
actual : Value ,
} ,
2019-03-15 15:11:31 +00:00
/// Tried to append a child to a leaf node.
/// Leaf nodes cannot have children.
AppendedToLeafNode ,
/// Tried to append a child to a node such that the precedence of the child is not higher.
2019-03-27 15:38:59 +00:00
/// This error should never occur.
/// If it does, please file a bug report.
2019-03-15 15:11:31 +00:00
PrecedenceViolation ,
2019-03-27 17:09:20 +00:00
/// A `VariableIdentifier` operation did not find its value in the context.
2019-03-18 17:21:07 +00:00
VariableIdentifierNotFound ( String ) ,
2019-03-27 17:09:20 +00:00
/// A `FunctionIdentifier` operation did not find its value in the context.
2019-03-18 17:21:07 +00:00
FunctionIdentifierNotFound ( String ) ,
2019-03-15 15:40:38 +00:00
2019-03-20 09:42:17 +00:00
/// A value has the wrong type.
/// Only use this if there is no other error that describes the expected and provided types in more detail.
TypeError {
/// The expected types.
2019-03-20 14:39:27 +00:00
expected : TupleType ,
2019-03-20 09:42:17 +00:00
/// The actual value.
actual : Value ,
} ,
2019-03-15 16:27:10 +00:00
/// An opening brace without a matching closing brace was found.
UnmatchedLBrace ,
/// A closing brace without a matching opening brace was found.
UnmatchedRBrace ,
2019-03-15 17:19:59 +00:00
2019-03-20 09:32:49 +00:00
/// A `PartialToken` is unmatched, such that it cannot be combined into a full `Token`.
/// This happens if for example a single `=` is found, surrounded by whitespace.
/// It is not a token, but it is part of the string representation of some tokens.
2019-03-15 17:19:59 +00:00
UnmatchedPartialToken {
2019-03-20 09:32:49 +00:00
/// The unmatched partial token.
2019-03-15 17:19:59 +00:00
first : PartialToken ,
2019-03-20 09:32:49 +00:00
/// 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.
2019-03-15 17:19:59 +00:00
second : Option < PartialToken > ,
} ,
2019-03-20 10:52:07 +00:00
/// An addition operation performed by Rust failed.
AdditionError {
/// The first argument of the addition.
augend : Value ,
/// The second argument of the addition.
addend : Value ,
} ,
/// A subtraction operation performed by Rust failed.
SubtractionError {
/// The first argument of the subtraction.
minuend : Value ,
/// The second argument of the subtraction.
subtrahend : Value ,
} ,
/// A negation operation performed by Rust failed.
NegationError {
/// The argument of the negation.
argument : Value ,
} ,
/// A multiplication operation performed by Rust failed.
MultiplicationError {
/// The first argument of the multiplication.
multiplicand : Value ,
/// The second argument of the multiplication.
multiplier : Value ,
} ,
/// A division operation performed by Rust failed.
DivisionError {
/// The first argument of the division.
dividend : Value ,
/// The second argument of the division.
divisor : Value ,
} ,
/// A modulation operation performed by Rust failed.
ModulationError {
/// The first argument of the modulation.
dividend : Value ,
/// The second argument of the modulation.
divisor : Value ,
} ,
2019-03-23 13:20:43 +00:00
2019-04-12 21:03:13 +00:00
/// A regular expression could not be parsed
2019-04-07 06:10:36 +00:00
InvalidRegex {
/// The invalid regular expression
regex : String ,
/// Failure message from the regex engine
message : String ,
} ,
2019-03-28 10:12:47 +00:00
/// A modification was attempted on a `Context` that does not allow modifications.
2019-03-27 15:38:59 +00:00
ContextNotManipulable ,
2019-03-30 10:54:19 +00:00
/// An escape sequence within a string literal is illegal.
IllegalEscapeSequence ( String ) ,
2019-03-23 13:20:43 +00:00
/// A custom error explained by its message.
2019-03-23 13:29:50 +00:00
CustomMessage ( String ) ,
2019-03-15 15:11:31 +00:00
}
2019-03-27 15:33:46 +00:00
impl EvalexprError {
2019-03-20 09:32:49 +00:00
pub ( crate ) fn wrong_operator_argument_amount ( actual : usize , expected : usize ) -> Self {
2019-03-27 15:33:46 +00:00
EvalexprError ::WrongOperatorArgumentAmount { actual , expected }
2019-03-19 14:54:52 +00:00
}
2019-03-20 09:32:49 +00:00
pub ( crate ) fn wrong_function_argument_amount ( actual : usize , expected : usize ) -> Self {
2019-03-27 15:33:46 +00:00
EvalexprError ::WrongFunctionArgumentAmount { actual , expected }
2019-03-15 15:11:31 +00:00
}
2019-03-20 09:42:17 +00:00
/// Constructs `Error::TypeError{actual, expected}`.
2019-03-20 14:39:27 +00:00
pub fn type_error ( actual : Value , expected : TupleType ) -> Self {
2019-03-27 15:33:46 +00:00
EvalexprError ::TypeError { actual , expected }
2019-03-20 09:42:17 +00:00
}
2019-03-28 08:56:30 +00:00
/// Constructs `Error::ExpectedString{actual}`.
2019-03-20 14:29:50 +00:00
pub fn expected_string ( actual : Value ) -> Self {
2019-03-27 15:33:46 +00:00
EvalexprError ::ExpectedString { actual }
2019-03-20 14:29:50 +00:00
}
2019-03-28 08:56:30 +00:00
/// Constructs `Error::ExpectedInt{actual}`.
2019-03-20 09:42:17 +00:00
pub fn expected_int ( actual : Value ) -> Self {
2019-03-27 15:33:46 +00:00
EvalexprError ::ExpectedInt { actual }
2019-03-20 09:42:17 +00:00
}
2019-03-28 08:56:30 +00:00
/// Constructs `Error::ExpectedFloat{actual}`.
2019-03-20 09:42:17 +00:00
pub fn expected_float ( actual : Value ) -> Self {
2019-03-27 15:33:46 +00:00
EvalexprError ::ExpectedFloat { actual }
2019-03-20 09:42:17 +00:00
}
2019-03-28 08:56:30 +00:00
/// Constructs `Error::ExpectedNumber{actual}`.
2019-03-15 15:11:31 +00:00
pub fn expected_number ( actual : Value ) -> Self {
2019-03-27 15:33:46 +00:00
EvalexprError ::ExpectedNumber { actual }
2019-03-15 15:11:31 +00:00
}
2019-03-15 17:19:59 +00:00
2019-04-05 21:07:54 +00:00
/// Constructs `Error::ExpectedNumberOrString{actual}`.
pub fn expected_number_or_string ( actual : Value ) -> Self {
EvalexprError ::ExpectedNumberOrString { actual }
}
2019-03-28 08:56:30 +00:00
/// Constructs `Error::ExpectedBoolean{actual}`.
2019-03-15 17:19:59 +00:00
pub fn expected_boolean ( actual : Value ) -> Self {
2019-03-27 15:33:46 +00:00
EvalexprError ::ExpectedBoolean { actual }
2019-03-15 17:19:59 +00:00
}
2019-03-28 08:56:30 +00:00
/// Constructs `Error::ExpectedTuple{actual}`.
2019-03-20 14:29:50 +00:00
pub fn expected_tuple ( actual : Value ) -> Self {
2019-03-27 15:33:46 +00:00
EvalexprError ::ExpectedTuple { actual }
2019-03-20 14:29:50 +00:00
}
2019-03-28 08:56:30 +00:00
/// Constructs `Error::ExpectedEmpty{actual}`.
pub fn expected_empty ( actual : Value ) -> Self {
EvalexprError ::ExpectedEmpty { actual }
}
2019-03-27 15:38:59 +00:00
/// Constructs an error that expresses that the type of `expected` was expected, but `actual` was found.
pub ( crate ) fn expected_type ( expected : & Value , actual : Value ) -> Self {
match ValueType ::from ( expected ) {
ValueType ::String = > Self ::expected_string ( actual ) ,
ValueType ::Int = > Self ::expected_int ( actual ) ,
ValueType ::Float = > Self ::expected_float ( actual ) ,
ValueType ::Boolean = > Self ::expected_boolean ( actual ) ,
ValueType ::Tuple = > Self ::expected_tuple ( actual ) ,
2019-03-28 08:56:30 +00:00
ValueType ::Empty = > Self ::expected_empty ( actual ) ,
2019-03-27 15:38:59 +00:00
}
}
2019-03-20 09:32:49 +00:00
pub ( crate ) fn unmatched_partial_token (
first : PartialToken ,
second : Option < PartialToken > ,
) -> Self {
2019-03-27 15:33:46 +00:00
EvalexprError ::UnmatchedPartialToken { first , second }
2019-03-15 17:19:59 +00:00
}
2019-03-20 10:52:07 +00:00
pub ( crate ) fn addition_error ( augend : Value , addend : Value ) -> Self {
2019-03-27 15:33:46 +00:00
EvalexprError ::AdditionError { augend , addend }
2019-03-20 10:52:07 +00:00
}
pub ( crate ) fn subtraction_error ( minuend : Value , subtrahend : Value ) -> Self {
2019-03-27 15:33:46 +00:00
EvalexprError ::SubtractionError {
2019-03-20 10:52:07 +00:00
minuend ,
subtrahend ,
}
}
pub ( crate ) fn negation_error ( argument : Value ) -> Self {
2019-03-27 15:33:46 +00:00
EvalexprError ::NegationError { argument }
2019-03-20 10:52:07 +00:00
}
pub ( crate ) fn multiplication_error ( multiplicand : Value , multiplier : Value ) -> Self {
2019-03-27 15:33:46 +00:00
EvalexprError ::MultiplicationError {
2019-03-20 10:52:07 +00:00
multiplicand ,
multiplier ,
}
}
pub ( crate ) fn division_error ( dividend : Value , divisor : Value ) -> Self {
2019-03-27 15:33:46 +00:00
EvalexprError ::DivisionError { dividend , divisor }
2019-03-20 10:52:07 +00:00
}
pub ( crate ) fn modulation_error ( dividend : Value , divisor : Value ) -> Self {
2019-03-27 15:33:46 +00:00
EvalexprError ::ModulationError { dividend , divisor }
2019-03-20 10:52:07 +00:00
}
2019-04-07 06:10:36 +00:00
/// Constructs `EvalexprError::InvalidRegex(regex)`
pub fn invalid_regex ( regex : String , message : String ) -> Self {
EvalexprError ::InvalidRegex { regex , message }
}
2019-03-15 15:11:31 +00:00
}
2019-03-20 09:32:49 +00:00
/// Returns `Ok(())` if the actual and expected parameters are equal, and `Err(Error::WrongOperatorArgumentAmount)` otherwise.
2019-03-27 15:38:59 +00:00
pub ( crate ) fn expect_operator_argument_amount (
actual : usize ,
expected : usize ,
2019-03-27 18:08:47 +00:00
) -> EvalexprResult < ( ) > {
2019-03-19 14:54:52 +00:00
if actual = = expected {
Ok ( ( ) )
} else {
2019-03-27 15:38:59 +00:00
Err ( EvalexprError ::wrong_operator_argument_amount (
actual , expected ,
) )
2019-03-19 14:54:52 +00:00
}
}
2019-03-20 09:32:49 +00:00
/// Returns `Ok(())` if the actual and expected parameters are equal, and `Err(Error::WrongFunctionArgumentAmount)` otherwise.
2019-03-31 13:46:22 +00:00
pub fn expect_function_argument_amount (
2019-03-27 15:38:59 +00:00
actual : usize ,
expected : usize ,
2019-03-27 18:08:47 +00:00
) -> EvalexprResult < ( ) > {
2019-03-15 15:11:31 +00:00
if actual = = expected {
Ok ( ( ) )
} else {
2019-03-27 15:38:59 +00:00
Err ( EvalexprError ::wrong_function_argument_amount (
actual , expected ,
) )
2019-03-15 15:11:31 +00:00
}
}
2019-03-28 10:12:47 +00:00
/// Returns `Ok(&str)` if the given value is a `Value::String`, or `Err(Error::ExpectedString)` otherwise.
pub fn expect_string ( actual : & Value ) -> EvalexprResult < & str > {
match actual {
Value ::String ( string ) = > Ok ( string ) ,
_ = > Err ( EvalexprError ::expected_string ( actual . clone ( ) ) ) ,
}
}
2019-03-20 09:32:49 +00:00
/// Returns `Ok(())` if the given value is numeric.
/// Numeric types are `Value::Int` and `Value::Float`.
/// Otherwise, `Err(Error::ExpectedNumber)` is returned.
2019-03-27 18:08:47 +00:00
pub fn expect_number ( actual : & Value ) -> EvalexprResult < ( ) > {
2019-03-15 15:11:31 +00:00
match actual {
2019-03-15 15:40:38 +00:00
Value ::Float ( _ ) | Value ::Int ( _ ) = > Ok ( ( ) ) ,
2019-03-27 15:33:46 +00:00
_ = > Err ( EvalexprError ::expected_number ( actual . clone ( ) ) ) ,
2016-11-16 16:12:26 +00:00
}
}
2019-03-15 17:19:59 +00:00
2019-04-05 21:07:54 +00:00
/// Returns Ok(()) if the given value is a string or a numeric
pub fn expect_number_or_string ( actual : & Value ) -> EvalexprResult < ( ) > {
match actual {
Value ::String ( _ ) | Value ::Float ( _ ) | Value ::Int ( _ ) = > Ok ( ( ) ) ,
_ = > Err ( EvalexprError ::expected_number_or_string ( actual . clone ( ) ) ) ,
}
}
2019-03-28 10:12:47 +00:00
/// Returns `Ok(bool)` if the given value is a `Value::Boolean`, or `Err(Error::ExpectedBoolean)` otherwise.
2019-03-27 18:08:47 +00:00
pub fn expect_boolean ( actual : & Value ) -> EvalexprResult < bool > {
2019-03-15 17:19:59 +00:00
match actual {
Value ::Boolean ( boolean ) = > Ok ( * boolean ) ,
2019-03-27 15:33:46 +00:00
_ = > Err ( EvalexprError ::expected_boolean ( actual . clone ( ) ) ) ,
2019-03-15 17:19:59 +00:00
}
2019-03-15 17:22:14 +00:00
}
2019-03-23 12:27:44 +00:00
2019-03-27 15:33:46 +00:00
impl std ::error ::Error for EvalexprError { }
2019-03-27 15:38:59 +00:00
/// Standard result type used by this crate.
pub type EvalexprResult < T > = Result < T , EvalexprError > ;