use fastn_resolved::evalexpr::{token::PartialToken, value::value_type::ValueType};
use fastn_resolved::evalexpr::{operator::Operator, value::Value};
mod display;
#[derive(Debug, PartialEq)]
#[non_exhaustive]
pub enum EvalexprError {
WrongOperatorArgumentAmount {
expected: usize,
actual: usize,
},
WrongFunctionArgumentAmount {
expected: usize,
actual: usize,
},
ExpectedString {
actual: Value,
},
ExpectedInt {
actual: Value,
},
ExpectedFloat {
actual: Value,
},
ExpectedNumber {
actual: Value,
},
ExpectedNumberOrString {
actual: Value,
},
ExpectedBoolean {
actual: Value,
},
ExpectedTuple {
actual: Value,
},
ExpectedFixedLenTuple {
expected_len: usize,
actual: Value,
},
ExpectedEmpty {
actual: Value,
},
AppendedToLeafNode,
PrecedenceViolation,
VariableIdentifierNotFound(String),
FunctionIdentifierNotFound(String),
TypeError {
expected: Vec<ValueType>,
actual: Value,
},
WrongTypeCombination {
operator: Operator,
actual: Vec<ValueType>,
},
UnmatchedLBrace,
UnmatchedRBrace,
MissingOperatorOutsideOfBrace,
UnmatchedPartialToken {
first: PartialToken,
second: Option<PartialToken>,
},
AdditionError {
augend: Value,
addend: Value,
},
SubtractionError {
minuend: Value,
subtrahend: Value,
},
NegationError {
argument: Value,
},
MultiplicationError {
multiplicand: Value,
multiplier: Value,
},
DivisionError {
dividend: Value,
divisor: Value,
},
ModulationError {
dividend: Value,
divisor: Value,
},
InvalidRegex {
regex: String,
message: String,
},
ContextNotMutable,
IllegalEscapeSequence(String),
CustomMessage(String),
}
impl EvalexprError {
pub(crate) fn wrong_operator_argument_amount(actual: usize, expected: usize) -> Self {
EvalexprError::WrongOperatorArgumentAmount { actual, expected }
}
pub(crate) fn wrong_function_argument_amount(actual: usize, expected: usize) -> Self {
EvalexprError::WrongFunctionArgumentAmount { actual, expected }
}
pub fn type_error(actual: Value, expected: Vec<ValueType>) -> Self {
EvalexprError::TypeError { actual, expected }
}
pub fn wrong_type_combination(operator: Operator, actual: Vec<ValueType>) -> Self {
EvalexprError::WrongTypeCombination { operator, actual }
}
pub fn expected_string(actual: Value) -> Self {
EvalexprError::ExpectedString { actual }
}
pub fn expected_int(actual: Value) -> Self {
EvalexprError::ExpectedInt { actual }
}
pub fn expected_float(actual: Value) -> Self {
EvalexprError::ExpectedFloat { actual }
}
pub fn expected_number(actual: Value) -> Self {
EvalexprError::ExpectedNumber { actual }
}
pub fn expected_number_or_string(actual: Value) -> Self {
EvalexprError::ExpectedNumberOrString { actual }
}
pub fn expected_boolean(actual: Value) -> Self {
EvalexprError::ExpectedBoolean { actual }
}
pub fn expected_tuple(actual: Value) -> Self {
EvalexprError::ExpectedTuple { actual }
}
pub fn expected_fixed_len_tuple(expected_len: usize, actual: Value) -> Self {
EvalexprError::ExpectedFixedLenTuple {
expected_len,
actual,
}
}
pub fn expected_empty(actual: Value) -> Self {
EvalexprError::ExpectedEmpty { actual }
}
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),
ValueType::Empty => Self::expected_empty(actual),
}
}
pub(crate) fn unmatched_partial_token(
first: PartialToken,
second: Option<PartialToken>,
) -> Self {
EvalexprError::UnmatchedPartialToken { first, second }
}
pub(crate) fn addition_error(augend: Value, addend: Value) -> Self {
EvalexprError::AdditionError { augend, addend }
}
pub(crate) fn subtraction_error(minuend: Value, subtrahend: Value) -> Self {
EvalexprError::SubtractionError {
minuend,
subtrahend,
}
}
pub(crate) fn negation_error(argument: Value) -> Self {
EvalexprError::NegationError { argument }
}
pub(crate) fn multiplication_error(multiplicand: Value, multiplier: Value) -> Self {
EvalexprError::MultiplicationError {
multiplicand,
multiplier,
}
}
pub(crate) fn division_error(dividend: Value, divisor: Value) -> Self {
EvalexprError::DivisionError { dividend, divisor }
}
pub(crate) fn modulation_error(dividend: Value, divisor: Value) -> Self {
EvalexprError::ModulationError { dividend, divisor }
}
pub fn invalid_regex(regex: String, message: String) -> Self {
EvalexprError::InvalidRegex { regex, message }
}
}
pub(crate) fn expect_operator_argument_amount(
actual: usize,
expected: usize,
) -> EvalexprResult<()> {
if actual == expected {
Ok(())
} else {
Err(EvalexprError::wrong_operator_argument_amount(
actual, expected,
))
}
}
pub fn expect_function_argument_amount(actual: usize, expected: usize) -> EvalexprResult<()> {
if actual == expected {
Ok(())
} else {
Err(EvalexprError::wrong_function_argument_amount(
actual, expected,
))
}
}
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())),
}
}
impl std::error::Error for EvalexprError {}
pub type EvalexprResult<T> = Result<T, EvalexprError>;
#[cfg(test)]
mod tests {
use fastn_resolved::evalexpr::{EvalexprError, Value, ValueType};
#[test]
fn trivial_coverage_tests() {
assert_eq!(
EvalexprError::type_error(Value::Int(3), vec![ValueType::String]),
EvalexprError::TypeError {
actual: Value::Int(3),
expected: vec![ValueType::String]
}
);
assert_eq!(
EvalexprError::expected_type(&Value::String("abc".to_string()), Value::Empty),
EvalexprError::expected_string(Value::Empty)
);
assert_eq!(
EvalexprError::expected_type(&Value::Boolean(false), Value::Empty),
EvalexprError::expected_boolean(Value::Empty)
);
assert_eq!(
EvalexprError::expected_type(&Value::Tuple(vec![]), Value::Empty),
EvalexprError::expected_tuple(Value::Empty)
);
assert_eq!(
EvalexprError::expected_type(&Value::Empty, Value::String("abc".to_string())),
EvalexprError::expected_empty(Value::String("abc".to_string()))
);
}
}