Format code
This commit is contained in:
parent
24ca11e52a
commit
b18521b8aa
@ -26,10 +26,18 @@ pub trait Context {
|
||||
/// The HashMapContext is type-safe and returns an error if the user tries to assign a value of a different type than before to an identifier.
|
||||
pub trait ContextMut: Context {
|
||||
/// Links the given value to the given identifier.
|
||||
fn set_value<S: Into<String>, V: Into<Value>>(&mut self, identifier: S, value: V) -> EvalexprResult<()>;
|
||||
fn set_value<S: Into<String>, V: Into<Value>>(
|
||||
&mut self,
|
||||
identifier: S,
|
||||
value: V,
|
||||
) -> EvalexprResult<()>;
|
||||
|
||||
/// Links the given function to the given identifier.
|
||||
fn set_function<S: Into<String>>(&mut self, identifier: S, function: Function) -> EvalexprResult<()>;
|
||||
fn set_function<S: Into<String>>(
|
||||
&mut self,
|
||||
identifier: S,
|
||||
function: Function,
|
||||
) -> EvalexprResult<()>;
|
||||
}
|
||||
|
||||
/// A context that returns `None` for each identifier.
|
||||
@ -46,11 +54,19 @@ impl Context for EmptyContext {
|
||||
}
|
||||
|
||||
impl ContextMut for EmptyContext {
|
||||
fn set_value<S: Into<String>, V: Into<Value>>(&mut self, _identifier: S, _value: V) -> EvalexprResult<()> {
|
||||
fn set_value<S: Into<String>, V: Into<Value>>(
|
||||
&mut self,
|
||||
_identifier: S,
|
||||
_value: V,
|
||||
) -> EvalexprResult<()> {
|
||||
Err(EvalexprError::ContextNotManipulable)
|
||||
}
|
||||
|
||||
fn set_function<S: Into<String>>(&mut self, _identifier: S, _function: Function) -> EvalexprResult<()> {
|
||||
fn set_function<S: Into<String>>(
|
||||
&mut self,
|
||||
_identifier: S,
|
||||
_function: Function,
|
||||
) -> EvalexprResult<()> {
|
||||
Err(EvalexprError::ContextNotManipulable)
|
||||
}
|
||||
}
|
||||
@ -86,7 +102,11 @@ impl Context for HashMapContext {
|
||||
}
|
||||
|
||||
impl ContextMut for HashMapContext {
|
||||
fn set_value<S: Into<String>, V: Into<Value>>(&mut self, identifier: S, value: V) -> Result<(), EvalexprError> {
|
||||
fn set_value<S: Into<String>, V: Into<Value>>(
|
||||
&mut self,
|
||||
identifier: S,
|
||||
value: V,
|
||||
) -> Result<(), EvalexprError> {
|
||||
let identifier = identifier.into();
|
||||
let value = value.into();
|
||||
if let Some(existing_value) = self.variables.get_mut(&identifier) {
|
||||
@ -103,8 +123,12 @@ impl ContextMut for HashMapContext {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn set_function<S: Into<String>>(&mut self, identifier: S, function: Function) -> Result<(), EvalexprError> {
|
||||
fn set_function<S: Into<String>>(
|
||||
&mut self,
|
||||
identifier: S,
|
||||
function: Function,
|
||||
) -> Result<(), EvalexprError> {
|
||||
self.functions.insert(identifier.into(), function);
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -6,8 +6,7 @@
|
||||
//! They are meant as shortcuts to not write the same error checking code everywhere.
|
||||
|
||||
use token::PartialToken;
|
||||
use value::TupleType;
|
||||
use value::value_type::ValueType;
|
||||
use value::{TupleType, value_type::ValueType};
|
||||
|
||||
use crate::value::Value;
|
||||
|
||||
|
@ -39,10 +39,7 @@ pub fn eval(string: &str) -> Result<Value, EvalexprError> {
|
||||
/// ```
|
||||
///
|
||||
/// *See the [crate doc](index.html) for more examples and explanations of the expression format.*
|
||||
pub fn eval_with_context(
|
||||
string: &str,
|
||||
context: &Context,
|
||||
) -> Result<Value, EvalexprError> {
|
||||
pub fn eval_with_context(string: &str, context: &Context) -> Result<Value, EvalexprError> {
|
||||
tree::tokens_to_operator_tree(token::tokenize(string)?)?.eval_with_context(context)
|
||||
}
|
||||
|
||||
@ -132,10 +129,7 @@ pub fn eval_tuple(string: &str) -> Result<TupleType, EvalexprError> {
|
||||
/// Evaluate the given expression string into a string with the given context.
|
||||
///
|
||||
/// *See the [crate doc](index.html) for more examples and explanations of the expression format.*
|
||||
pub fn eval_string_with_context(
|
||||
string: &str,
|
||||
context: &Context,
|
||||
) -> Result<String, EvalexprError> {
|
||||
pub fn eval_string_with_context(string: &str, context: &Context) -> Result<String, EvalexprError> {
|
||||
match eval_with_context(string, context) {
|
||||
Ok(Value::String(string)) => Ok(string),
|
||||
Ok(value) => Err(EvalexprError::expected_string(value)),
|
||||
@ -146,10 +140,7 @@ pub fn eval_string_with_context(
|
||||
/// Evaluate the given expression string into an integer with the given context.
|
||||
///
|
||||
/// *See the [crate doc](index.html) for more examples and explanations of the expression format.*
|
||||
pub fn eval_int_with_context(
|
||||
string: &str,
|
||||
context: &Context,
|
||||
) -> Result<IntType, EvalexprError> {
|
||||
pub fn eval_int_with_context(string: &str, context: &Context) -> Result<IntType, EvalexprError> {
|
||||
match eval_with_context(string, context) {
|
||||
Ok(Value::Int(int)) => Ok(int),
|
||||
Ok(value) => Err(EvalexprError::expected_int(value)),
|
||||
@ -174,10 +165,7 @@ pub fn eval_float_with_context(
|
||||
/// Evaluate the given expression string into a boolean with the given context.
|
||||
///
|
||||
/// *See the [crate doc](index.html) for more examples and explanations of the expression format.*
|
||||
pub fn eval_boolean_with_context(
|
||||
string: &str,
|
||||
context: &Context,
|
||||
) -> Result<bool, EvalexprError> {
|
||||
pub fn eval_boolean_with_context(string: &str, context: &Context) -> Result<bool, EvalexprError> {
|
||||
match eval_with_context(string, context) {
|
||||
Ok(Value::Boolean(boolean)) => Ok(boolean),
|
||||
Ok(value) => Err(EvalexprError::expected_boolean(value)),
|
||||
|
@ -29,11 +29,7 @@ pub trait Operator: Debug + Display {
|
||||
fn argument_amount(&self) -> usize;
|
||||
|
||||
/// Evaluates the operator with the given arguments and context.
|
||||
fn eval(
|
||||
&self,
|
||||
arguments: &[Value],
|
||||
context: &Context,
|
||||
) -> Result<Value, EvalexprError>;
|
||||
fn eval(&self, arguments: &[Value], context: &Context) -> Result<Value, EvalexprError>;
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
@ -122,11 +118,7 @@ impl Operator for RootNode {
|
||||
1
|
||||
}
|
||||
|
||||
fn eval(
|
||||
&self,
|
||||
arguments: &[Value],
|
||||
_context: &Context,
|
||||
) -> Result<Value, EvalexprError> {
|
||||
fn eval(&self, arguments: &[Value], _context: &Context) -> Result<Value, EvalexprError> {
|
||||
expect_operator_argument_amount(arguments.len(), 1)?;
|
||||
Ok(arguments[0].clone())
|
||||
}
|
||||
@ -145,11 +137,7 @@ impl Operator for Add {
|
||||
2
|
||||
}
|
||||
|
||||
fn eval(
|
||||
&self,
|
||||
arguments: &[Value],
|
||||
_context: &Context,
|
||||
) -> Result<Value, EvalexprError> {
|
||||
fn eval(&self, arguments: &[Value], _context: &Context) -> Result<Value, EvalexprError> {
|
||||
expect_operator_argument_amount(arguments.len(), 2)?;
|
||||
expect_number(&arguments[0])?;
|
||||
expect_number(&arguments[1])?;
|
||||
@ -185,11 +173,7 @@ impl Operator for Sub {
|
||||
2
|
||||
}
|
||||
|
||||
fn eval(
|
||||
&self,
|
||||
arguments: &[Value],
|
||||
_context: &Context,
|
||||
) -> Result<Value, EvalexprError> {
|
||||
fn eval(&self, arguments: &[Value], _context: &Context) -> Result<Value, EvalexprError> {
|
||||
expect_operator_argument_amount(arguments.len(), 2)?;
|
||||
expect_number(&arguments[0])?;
|
||||
expect_number(&arguments[1])?;
|
||||
@ -225,11 +209,7 @@ impl Operator for Neg {
|
||||
1
|
||||
}
|
||||
|
||||
fn eval(
|
||||
&self,
|
||||
arguments: &[Value],
|
||||
_context: &Context,
|
||||
) -> Result<Value, EvalexprError> {
|
||||
fn eval(&self, arguments: &[Value], _context: &Context) -> Result<Value, EvalexprError> {
|
||||
expect_operator_argument_amount(arguments.len(), 1)?;
|
||||
expect_number(&arguments[0])?;
|
||||
|
||||
@ -259,11 +239,7 @@ impl Operator for Mul {
|
||||
2
|
||||
}
|
||||
|
||||
fn eval(
|
||||
&self,
|
||||
arguments: &[Value],
|
||||
_context: &Context,
|
||||
) -> Result<Value, EvalexprError> {
|
||||
fn eval(&self, arguments: &[Value], _context: &Context) -> Result<Value, EvalexprError> {
|
||||
expect_operator_argument_amount(arguments.len(), 2)?;
|
||||
expect_number(&arguments[0])?;
|
||||
expect_number(&arguments[1])?;
|
||||
@ -299,11 +275,7 @@ impl Operator for Div {
|
||||
2
|
||||
}
|
||||
|
||||
fn eval(
|
||||
&self,
|
||||
arguments: &[Value],
|
||||
_context: &Context,
|
||||
) -> Result<Value, EvalexprError> {
|
||||
fn eval(&self, arguments: &[Value], _context: &Context) -> Result<Value, EvalexprError> {
|
||||
expect_operator_argument_amount(arguments.len(), 2)?;
|
||||
expect_number(&arguments[0])?;
|
||||
expect_number(&arguments[1])?;
|
||||
@ -339,11 +311,7 @@ impl Operator for Mod {
|
||||
2
|
||||
}
|
||||
|
||||
fn eval(
|
||||
&self,
|
||||
arguments: &[Value],
|
||||
_context: &Context,
|
||||
) -> Result<Value, EvalexprError> {
|
||||
fn eval(&self, arguments: &[Value], _context: &Context) -> Result<Value, EvalexprError> {
|
||||
expect_operator_argument_amount(arguments.len(), 2)?;
|
||||
expect_number(&arguments[0])?;
|
||||
expect_number(&arguments[1])?;
|
||||
@ -379,11 +347,7 @@ impl Operator for Exp {
|
||||
2
|
||||
}
|
||||
|
||||
fn eval(
|
||||
&self,
|
||||
arguments: &[Value],
|
||||
_context: &Context,
|
||||
) -> Result<Value, EvalexprError> {
|
||||
fn eval(&self, arguments: &[Value], _context: &Context) -> Result<Value, EvalexprError> {
|
||||
expect_operator_argument_amount(arguments.len(), 2)?;
|
||||
expect_number(&arguments[0])?;
|
||||
expect_number(&arguments[1])?;
|
||||
@ -410,11 +374,7 @@ impl Operator for Eq {
|
||||
2
|
||||
}
|
||||
|
||||
fn eval(
|
||||
&self,
|
||||
arguments: &[Value],
|
||||
_context: &Context,
|
||||
) -> Result<Value, EvalexprError> {
|
||||
fn eval(&self, arguments: &[Value], _context: &Context) -> Result<Value, EvalexprError> {
|
||||
expect_operator_argument_amount(arguments.len(), 2)?;
|
||||
|
||||
if arguments[0] == arguments[1] {
|
||||
@ -438,11 +398,7 @@ impl Operator for Neq {
|
||||
2
|
||||
}
|
||||
|
||||
fn eval(
|
||||
&self,
|
||||
arguments: &[Value],
|
||||
_context: &Context,
|
||||
) -> Result<Value, EvalexprError> {
|
||||
fn eval(&self, arguments: &[Value], _context: &Context) -> Result<Value, EvalexprError> {
|
||||
expect_operator_argument_amount(arguments.len(), 2)?;
|
||||
|
||||
if arguments[0] != arguments[1] {
|
||||
@ -466,11 +422,7 @@ impl Operator for Gt {
|
||||
2
|
||||
}
|
||||
|
||||
fn eval(
|
||||
&self,
|
||||
arguments: &[Value],
|
||||
_context: &Context,
|
||||
) -> Result<Value, EvalexprError> {
|
||||
fn eval(&self, arguments: &[Value], _context: &Context) -> Result<Value, EvalexprError> {
|
||||
expect_operator_argument_amount(arguments.len(), 2)?;
|
||||
expect_number(&arguments[0])?;
|
||||
expect_number(&arguments[1])?;
|
||||
@ -504,11 +456,7 @@ impl Operator for Lt {
|
||||
2
|
||||
}
|
||||
|
||||
fn eval(
|
||||
&self,
|
||||
arguments: &[Value],
|
||||
_context: &Context,
|
||||
) -> Result<Value, EvalexprError> {
|
||||
fn eval(&self, arguments: &[Value], _context: &Context) -> Result<Value, EvalexprError> {
|
||||
expect_operator_argument_amount(arguments.len(), 2)?;
|
||||
expect_number(&arguments[0])?;
|
||||
expect_number(&arguments[1])?;
|
||||
@ -542,11 +490,7 @@ impl Operator for Geq {
|
||||
2
|
||||
}
|
||||
|
||||
fn eval(
|
||||
&self,
|
||||
arguments: &[Value],
|
||||
_context: &Context,
|
||||
) -> Result<Value, EvalexprError> {
|
||||
fn eval(&self, arguments: &[Value], _context: &Context) -> Result<Value, EvalexprError> {
|
||||
expect_operator_argument_amount(arguments.len(), 2)?;
|
||||
expect_number(&arguments[0])?;
|
||||
expect_number(&arguments[1])?;
|
||||
@ -580,11 +524,7 @@ impl Operator for Leq {
|
||||
2
|
||||
}
|
||||
|
||||
fn eval(
|
||||
&self,
|
||||
arguments: &[Value],
|
||||
_context: &Context,
|
||||
) -> Result<Value, EvalexprError> {
|
||||
fn eval(&self, arguments: &[Value], _context: &Context) -> Result<Value, EvalexprError> {
|
||||
expect_operator_argument_amount(arguments.len(), 2)?;
|
||||
expect_number(&arguments[0])?;
|
||||
expect_number(&arguments[1])?;
|
||||
@ -618,11 +558,7 @@ impl Operator for And {
|
||||
2
|
||||
}
|
||||
|
||||
fn eval(
|
||||
&self,
|
||||
arguments: &[Value],
|
||||
_context: &Context,
|
||||
) -> Result<Value, EvalexprError> {
|
||||
fn eval(&self, arguments: &[Value], _context: &Context) -> Result<Value, EvalexprError> {
|
||||
expect_operator_argument_amount(arguments.len(), 2)?;
|
||||
let a = expect_boolean(&arguments[0])?;
|
||||
let b = expect_boolean(&arguments[1])?;
|
||||
@ -648,11 +584,7 @@ impl Operator for Or {
|
||||
2
|
||||
}
|
||||
|
||||
fn eval(
|
||||
&self,
|
||||
arguments: &[Value],
|
||||
_context: &Context,
|
||||
) -> Result<Value, EvalexprError> {
|
||||
fn eval(&self, arguments: &[Value], _context: &Context) -> Result<Value, EvalexprError> {
|
||||
expect_operator_argument_amount(arguments.len(), 2)?;
|
||||
let a = expect_boolean(&arguments[0])?;
|
||||
let b = expect_boolean(&arguments[1])?;
|
||||
@ -678,11 +610,7 @@ impl Operator for Not {
|
||||
1
|
||||
}
|
||||
|
||||
fn eval(
|
||||
&self,
|
||||
arguments: &[Value],
|
||||
_context: &Context,
|
||||
) -> Result<Value, EvalexprError> {
|
||||
fn eval(&self, arguments: &[Value], _context: &Context) -> Result<Value, EvalexprError> {
|
||||
expect_operator_argument_amount(arguments.len(), 1)?;
|
||||
let a = expect_boolean(&arguments[0])?;
|
||||
|
||||
@ -707,11 +635,7 @@ impl Operator for Tuple {
|
||||
2
|
||||
}
|
||||
|
||||
fn eval(
|
||||
&self,
|
||||
arguments: &[Value],
|
||||
_context: &Context,
|
||||
) -> Result<Value, EvalexprError> {
|
||||
fn eval(&self, arguments: &[Value], _context: &Context) -> Result<Value, EvalexprError> {
|
||||
if let Value::Tuple(tuple) = &arguments[0] {
|
||||
let mut tuple = tuple.clone();
|
||||
if let Value::Tuple(tuple2) = &arguments[1] {
|
||||
@ -748,11 +672,7 @@ impl Operator for Const {
|
||||
0
|
||||
}
|
||||
|
||||
fn eval(
|
||||
&self,
|
||||
arguments: &[Value],
|
||||
_context: &Context,
|
||||
) -> Result<Value, EvalexprError> {
|
||||
fn eval(&self, arguments: &[Value], _context: &Context) -> Result<Value, EvalexprError> {
|
||||
expect_operator_argument_amount(arguments.len(), 0)?;
|
||||
|
||||
Ok(self.value.clone())
|
||||
@ -772,11 +692,7 @@ impl Operator for VariableIdentifier {
|
||||
0
|
||||
}
|
||||
|
||||
fn eval(
|
||||
&self,
|
||||
_arguments: &[Value],
|
||||
context: &Context,
|
||||
) -> Result<Value, EvalexprError> {
|
||||
fn eval(&self, _arguments: &[Value], context: &Context) -> Result<Value, EvalexprError> {
|
||||
if let Some(value) = context.get_value(&self.identifier).cloned() {
|
||||
Ok(value)
|
||||
} else {
|
||||
@ -800,11 +716,7 @@ impl Operator for FunctionIdentifier {
|
||||
1
|
||||
}
|
||||
|
||||
fn eval(
|
||||
&self,
|
||||
arguments: &[Value],
|
||||
context: &Context,
|
||||
) -> Result<Value, EvalexprError> {
|
||||
fn eval(&self, arguments: &[Value], context: &Context) -> Result<Value, EvalexprError> {
|
||||
expect_operator_argument_amount(arguments.len(), 1)?;
|
||||
|
||||
let arguments = if let Value::Tuple(arguments) = &arguments[0] {
|
||||
|
@ -46,10 +46,7 @@ impl Node {
|
||||
/// Evaluates the operator tree rooted at this node with the given context.
|
||||
///
|
||||
/// Fails, if one of the operators in the expression tree fails.
|
||||
pub fn eval_with_context(
|
||||
&self,
|
||||
context: &Context,
|
||||
) -> Result<Value, EvalexprError> {
|
||||
pub fn eval_with_context(&self, context: &Context) -> Result<Value, EvalexprError> {
|
||||
let mut arguments = Vec::new();
|
||||
for child in self.children() {
|
||||
arguments.push(child.eval_with_context(context)?);
|
||||
@ -67,10 +64,7 @@ impl Node {
|
||||
/// Evaluates the operator tree rooted at this node into a string with an the given context.
|
||||
///
|
||||
/// Fails, if one of the operators in the expression tree fails.
|
||||
pub fn eval_string_with_context(
|
||||
&self,
|
||||
context: &Context,
|
||||
) -> Result<String, EvalexprError> {
|
||||
pub fn eval_string_with_context(&self, context: &Context) -> Result<String, EvalexprError> {
|
||||
match self.eval_with_context(context) {
|
||||
Ok(Value::String(string)) => Ok(string),
|
||||
Ok(value) => Err(EvalexprError::expected_string(value)),
|
||||
@ -81,10 +75,7 @@ impl Node {
|
||||
/// Evaluates the operator tree rooted at this node into a float with an the given context.
|
||||
///
|
||||
/// Fails, if one of the operators in the expression tree fails.
|
||||
pub fn eval_float_with_context(
|
||||
&self,
|
||||
context: &Context,
|
||||
) -> Result<FloatType, EvalexprError> {
|
||||
pub fn eval_float_with_context(&self, context: &Context) -> Result<FloatType, EvalexprError> {
|
||||
match self.eval_with_context(context) {
|
||||
Ok(Value::Float(float)) => Ok(float),
|
||||
Ok(value) => Err(EvalexprError::expected_float(value)),
|
||||
@ -95,10 +86,7 @@ impl Node {
|
||||
/// Evaluates the operator tree rooted at this node into an integer with an the given context.
|
||||
///
|
||||
/// Fails, if one of the operators in the expression tree fails.
|
||||
pub fn eval_int_with_context(
|
||||
&self,
|
||||
context: &Context,
|
||||
) -> Result<IntType, EvalexprError> {
|
||||
pub fn eval_int_with_context(&self, context: &Context) -> Result<IntType, EvalexprError> {
|
||||
match self.eval_with_context(context) {
|
||||
Ok(Value::Int(int)) => Ok(int),
|
||||
Ok(value) => Err(EvalexprError::expected_int(value)),
|
||||
@ -109,10 +97,7 @@ impl Node {
|
||||
/// Evaluates the operator tree rooted at this node into a boolean with an the given context.
|
||||
///
|
||||
/// Fails, if one of the operators in the expression tree fails.
|
||||
pub fn eval_boolean_with_context(
|
||||
&self,
|
||||
context: &Context,
|
||||
) -> Result<bool, EvalexprError> {
|
||||
pub fn eval_boolean_with_context(&self, context: &Context) -> Result<bool, EvalexprError> {
|
||||
match self.eval_with_context(context) {
|
||||
Ok(Value::Boolean(boolean)) => Ok(boolean),
|
||||
Ok(value) => Err(EvalexprError::expected_boolean(value)),
|
||||
@ -123,10 +108,7 @@ impl Node {
|
||||
/// Evaluates the operator tree rooted at this node into a tuple with an the given context.
|
||||
///
|
||||
/// Fails, if one of the operators in the expression tree fails.
|
||||
pub fn eval_tuple_with_context(
|
||||
&self,
|
||||
context: &Context,
|
||||
) -> Result<TupleType, EvalexprError> {
|
||||
pub fn eval_tuple_with_context(&self, context: &Context) -> Result<TupleType, EvalexprError> {
|
||||
match self.eval_with_context(context) {
|
||||
Ok(Value::Tuple(tuple)) => Ok(tuple),
|
||||
Ok(value) => Err(EvalexprError::expected_tuple(value)),
|
||||
|
@ -37,4 +37,4 @@ impl From<&&mut Value> for ValueType {
|
||||
fn from(value: &&mut Value) -> Self {
|
||||
From::<&Value>::from(*value)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -107,14 +107,8 @@ fn test_with_context() {
|
||||
context.set_value("half", Value::Float(0.5)).unwrap();
|
||||
context.set_value("zero", Value::Int(0)).unwrap();
|
||||
|
||||
assert_eq!(
|
||||
eval_with_context("tr", &context),
|
||||
Ok(Value::Boolean(true))
|
||||
);
|
||||
assert_eq!(
|
||||
eval_with_context("fa", &context),
|
||||
Ok(Value::Boolean(false))
|
||||
);
|
||||
assert_eq!(eval_with_context("tr", &context), Ok(Value::Boolean(true)));
|
||||
assert_eq!(eval_with_context("fa", &context), Ok(Value::Boolean(false)));
|
||||
assert_eq!(
|
||||
eval_with_context("tr && false", &context),
|
||||
Ok(Value::Boolean(false))
|
||||
@ -136,39 +130,31 @@ fn test_with_context() {
|
||||
#[test]
|
||||
fn test_functions() {
|
||||
let mut context = HashMapContext::new();
|
||||
context.set_function(
|
||||
"sub2".to_string(),
|
||||
Function::new(
|
||||
Some(1),
|
||||
Box::new(|arguments| {
|
||||
if let Value::Int(int) = arguments[0] {
|
||||
Ok(Value::Int(int - 2))
|
||||
} else if let Value::Float(float) = arguments[0] {
|
||||
Ok(Value::Float(float - 2.0))
|
||||
} else {
|
||||
Err(EvalexprError::expected_number(arguments[0].clone()))
|
||||
}
|
||||
}),
|
||||
),
|
||||
).unwrap();
|
||||
context.set_value("five".to_string(), Value::Int(5)).unwrap();
|
||||
context
|
||||
.set_function(
|
||||
"sub2".to_string(),
|
||||
Function::new(
|
||||
Some(1),
|
||||
Box::new(|arguments| {
|
||||
if let Value::Int(int) = arguments[0] {
|
||||
Ok(Value::Int(int - 2))
|
||||
} else if let Value::Float(float) = arguments[0] {
|
||||
Ok(Value::Float(float - 2.0))
|
||||
} else {
|
||||
Err(EvalexprError::expected_number(arguments[0].clone()))
|
||||
}
|
||||
}),
|
||||
),
|
||||
)
|
||||
.unwrap();
|
||||
context
|
||||
.set_value("five".to_string(), Value::Int(5))
|
||||
.unwrap();
|
||||
|
||||
assert_eq!(
|
||||
eval_with_context("sub2 5", &context),
|
||||
Ok(Value::Int(3))
|
||||
);
|
||||
assert_eq!(
|
||||
eval_with_context("sub2(5)", &context),
|
||||
Ok(Value::Int(3))
|
||||
);
|
||||
assert_eq!(
|
||||
eval_with_context("sub2 five", &context),
|
||||
Ok(Value::Int(3))
|
||||
);
|
||||
assert_eq!(
|
||||
eval_with_context("sub2(five)", &context),
|
||||
Ok(Value::Int(3))
|
||||
);
|
||||
assert_eq!(eval_with_context("sub2 5", &context), Ok(Value::Int(3)));
|
||||
assert_eq!(eval_with_context("sub2(5)", &context), Ok(Value::Int(3)));
|
||||
assert_eq!(eval_with_context("sub2 five", &context), Ok(Value::Int(3)));
|
||||
assert_eq!(eval_with_context("sub2(five)", &context), Ok(Value::Int(3)));
|
||||
assert_eq!(
|
||||
eval_with_context("sub2(3) + five", &context),
|
||||
Ok(Value::Int(6))
|
||||
@ -178,74 +164,81 @@ fn test_functions() {
|
||||
#[test]
|
||||
fn test_n_ary_functions() {
|
||||
let mut context = HashMapContext::new();
|
||||
context.set_function(
|
||||
"sub2",
|
||||
Function::new(
|
||||
Some(1),
|
||||
Box::new(|arguments| {
|
||||
if let Value::Int(int) = arguments[0] {
|
||||
Ok(Value::Int(int - 2))
|
||||
} else if let Value::Float(float) = arguments[0] {
|
||||
Ok(Value::Float(float - 2.0))
|
||||
} else {
|
||||
Err(EvalexprError::expected_number(arguments[0].clone()))
|
||||
}
|
||||
}),
|
||||
),
|
||||
).unwrap();
|
||||
context.set_function(
|
||||
"avg",
|
||||
Function::new(
|
||||
Some(2),
|
||||
Box::new(|arguments| {
|
||||
expect_number(&arguments[0])?;
|
||||
expect_number(&arguments[1])?;
|
||||
context
|
||||
.set_function(
|
||||
"sub2",
|
||||
Function::new(
|
||||
Some(1),
|
||||
Box::new(|arguments| {
|
||||
if let Value::Int(int) = arguments[0] {
|
||||
Ok(Value::Int(int - 2))
|
||||
} else if let Value::Float(float) = arguments[0] {
|
||||
Ok(Value::Float(float - 2.0))
|
||||
} else {
|
||||
Err(EvalexprError::expected_number(arguments[0].clone()))
|
||||
}
|
||||
}),
|
||||
),
|
||||
)
|
||||
.unwrap();
|
||||
context
|
||||
.set_function(
|
||||
"avg",
|
||||
Function::new(
|
||||
Some(2),
|
||||
Box::new(|arguments| {
|
||||
expect_number(&arguments[0])?;
|
||||
expect_number(&arguments[1])?;
|
||||
|
||||
if let (Value::Int(a), Value::Int(b)) = (&arguments[0], &arguments[1]) {
|
||||
Ok(Value::Int((a + b) / 2))
|
||||
} else {
|
||||
Ok(Value::Float(
|
||||
(arguments[0].as_float()? + arguments[1].as_float()?) / 2.0,
|
||||
))
|
||||
}
|
||||
}),
|
||||
),
|
||||
).unwrap();
|
||||
context.set_function(
|
||||
"muladd",
|
||||
Function::new(
|
||||
Some(3),
|
||||
Box::new(|arguments| {
|
||||
expect_number(&arguments[0])?;
|
||||
expect_number(&arguments[1])?;
|
||||
expect_number(&arguments[2])?;
|
||||
if let (Value::Int(a), Value::Int(b)) = (&arguments[0], &arguments[1]) {
|
||||
Ok(Value::Int((a + b) / 2))
|
||||
} else {
|
||||
Ok(Value::Float(
|
||||
(arguments[0].as_float()? + arguments[1].as_float()?) / 2.0,
|
||||
))
|
||||
}
|
||||
}),
|
||||
),
|
||||
)
|
||||
.unwrap();
|
||||
context
|
||||
.set_function(
|
||||
"muladd",
|
||||
Function::new(
|
||||
Some(3),
|
||||
Box::new(|arguments| {
|
||||
expect_number(&arguments[0])?;
|
||||
expect_number(&arguments[1])?;
|
||||
expect_number(&arguments[2])?;
|
||||
|
||||
if let (Value::Int(a), Value::Int(b), Value::Int(c)) =
|
||||
if let (Value::Int(a), Value::Int(b), Value::Int(c)) =
|
||||
(&arguments[0], &arguments[1], &arguments[2])
|
||||
{
|
||||
Ok(Value::Int(a * b + c))
|
||||
} else {
|
||||
Ok(Value::Float(
|
||||
arguments[0].as_float()? * arguments[1].as_float()?
|
||||
+ arguments[2].as_float()?,
|
||||
))
|
||||
}
|
||||
}),
|
||||
),
|
||||
).unwrap();
|
||||
context.set_function(
|
||||
"count",
|
||||
Function::new(
|
||||
None,
|
||||
Box::new(|arguments| Ok(Value::Int(arguments.len() as IntType))),
|
||||
),
|
||||
).unwrap();
|
||||
context.set_value("five".to_string(), Value::Int(5)).unwrap();
|
||||
{
|
||||
Ok(Value::Int(a * b + c))
|
||||
} else {
|
||||
Ok(Value::Float(
|
||||
arguments[0].as_float()? * arguments[1].as_float()?
|
||||
+ arguments[2].as_float()?,
|
||||
))
|
||||
}
|
||||
}),
|
||||
),
|
||||
)
|
||||
.unwrap();
|
||||
context
|
||||
.set_function(
|
||||
"count",
|
||||
Function::new(
|
||||
None,
|
||||
Box::new(|arguments| Ok(Value::Int(arguments.len() as IntType))),
|
||||
),
|
||||
)
|
||||
.unwrap();
|
||||
context
|
||||
.set_value("five".to_string(), Value::Int(5))
|
||||
.unwrap();
|
||||
|
||||
assert_eq!(
|
||||
eval_with_context("avg(7, 5)", &context),
|
||||
Ok(Value::Int(6))
|
||||
);
|
||||
assert_eq!(eval_with_context("avg(7, 5)", &context), Ok(Value::Int(6)));
|
||||
assert_eq!(
|
||||
eval_with_context("avg(sub2 5, 5)", &context),
|
||||
Ok(Value::Int(4))
|
||||
@ -273,10 +266,7 @@ fn test_n_ary_functions() {
|
||||
eval_with_context("count(3, 5.5, 2)", &context),
|
||||
Ok(Value::Int(3))
|
||||
);
|
||||
assert_eq!(
|
||||
eval_with_context("count 5", &context),
|
||||
Ok(Value::Int(1))
|
||||
);
|
||||
assert_eq!(eval_with_context("count 5", &context), Ok(Value::Int(1)));
|
||||
|
||||
assert_eq!(
|
||||
eval_with_context("min(4.0, 3)", &context),
|
||||
@ -342,7 +332,9 @@ fn test_no_panic() {
|
||||
#[test]
|
||||
fn test_shortcut_functions() {
|
||||
let mut context = HashMapContext::new();
|
||||
context.set_value("string", Value::from("a string")).unwrap();
|
||||
context
|
||||
.set_value("string", Value::from("a string"))
|
||||
.unwrap();
|
||||
|
||||
// assert_eq!(eval_string("???"));
|
||||
assert_eq!(
|
||||
@ -350,17 +342,11 @@ fn test_shortcut_functions() {
|
||||
Ok("a string".to_string())
|
||||
);
|
||||
assert_eq!(eval_float("3.3"), Ok(3.3));
|
||||
assert_eq!(
|
||||
eval_float_with_context("3.3", &context),
|
||||
Ok(3.3)
|
||||
);
|
||||
assert_eq!(eval_float_with_context("3.3", &context), Ok(3.3));
|
||||
assert_eq!(eval_int("3"), Ok(3));
|
||||
assert_eq!(eval_int_with_context("3", &context), Ok(3));
|
||||
assert_eq!(eval_boolean("true"), Ok(true));
|
||||
assert_eq!(
|
||||
eval_boolean_with_context("true", &context),
|
||||
Ok(true)
|
||||
);
|
||||
assert_eq!(eval_boolean_with_context("true", &context), Ok(true));
|
||||
assert_eq!(eval_tuple("3,3"), Ok(vec![Value::Int(3), Value::Int(3)]));
|
||||
assert_eq!(
|
||||
eval_tuple_with_context("3,3", &context),
|
||||
|
Loading…
Reference in New Issue
Block a user