parent
a7b5f602d5
commit
7d36ebe8df
@ -12,7 +12,7 @@ pub(crate) mod builtin;
|
|||||||
/// use evalexpr::*;
|
/// use evalexpr::*;
|
||||||
///
|
///
|
||||||
/// let mut context = HashMapContext::new();
|
/// let mut context = HashMapContext::new();
|
||||||
/// context.set_function("id", Function::new(Some(1), Box::new(|arguments| {
|
/// context.set_function("id".into(), Function::new(Some(1), Box::new(|arguments| {
|
||||||
/// Ok(arguments[0].clone())
|
/// Ok(arguments[0].clone())
|
||||||
/// }))).unwrap(); // Do proper error handling here
|
/// }))).unwrap(); // Do proper error handling here
|
||||||
/// assert_eq!(eval_with_context("id(4)", &context), Ok(Value::from(4)));
|
/// assert_eq!(eval_with_context("id(4)", &context), Ok(Value::from(4)));
|
||||||
|
@ -282,7 +282,9 @@ pub use error::{EvalexprError, EvalexprResult};
|
|||||||
pub use function::Function;
|
pub use function::Function;
|
||||||
pub use interface::*;
|
pub use interface::*;
|
||||||
pub use tree::Node;
|
pub use tree::Node;
|
||||||
pub use value::{EmptyType, FloatType, IntType, TupleType, Value, value_type::ValueType};
|
pub use value::{
|
||||||
|
EMPTY_VALUE, EmptyType, FloatType, IntType, TupleType, Value, value_type::ValueType,
|
||||||
|
};
|
||||||
|
|
||||||
mod context;
|
mod context;
|
||||||
pub mod error;
|
pub mod error;
|
||||||
|
@ -1,8 +1,9 @@
|
|||||||
use EmptyContext;
|
use EmptyContext;
|
||||||
|
use EmptyType;
|
||||||
use FloatType;
|
use FloatType;
|
||||||
use IntType;
|
use IntType;
|
||||||
use token::Token;
|
use token::Token;
|
||||||
use value::TupleType;
|
use value::{EMPTY_VALUE, TupleType};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
context::Context,
|
context::Context,
|
||||||
@ -145,6 +146,17 @@ impl Node {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Evaluates the operator tree rooted at this node into an empty value with an the given context.
|
||||||
|
///
|
||||||
|
/// Fails, if one of the operators in the expression tree fails.
|
||||||
|
pub fn eval_empty_with_context(&self, context: &Context) -> EvalexprResult<EmptyType> {
|
||||||
|
match self.eval_with_context(context) {
|
||||||
|
Ok(Value::Empty) => Ok(EMPTY_VALUE),
|
||||||
|
Ok(value) => Err(EvalexprError::expected_empty(value)),
|
||||||
|
Err(error) => Err(error),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Evaluates the operator tree rooted at this node into a string with an the given mutable context.
|
/// Evaluates the operator tree rooted at this node into a string with an the given mutable context.
|
||||||
///
|
///
|
||||||
/// Fails, if one of the operators in the expression tree fails.
|
/// Fails, if one of the operators in the expression tree fails.
|
||||||
@ -213,6 +225,17 @@ impl Node {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Evaluates the operator tree rooted at this node into an empty value with an the given mutable context.
|
||||||
|
///
|
||||||
|
/// Fails, if one of the operators in the expression tree fails.
|
||||||
|
pub fn eval_empty_with_context_mut(&self, context: &mut Context) -> EvalexprResult<EmptyType> {
|
||||||
|
match self.eval_with_context_mut(context) {
|
||||||
|
Ok(Value::Empty) => Ok(EMPTY_VALUE),
|
||||||
|
Ok(value) => Err(EvalexprError::expected_empty(value)),
|
||||||
|
Err(error) => Err(error),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Evaluates the operator tree rooted at this node into a string with an empty context.
|
/// Evaluates the operator tree rooted at this node into a string with an empty context.
|
||||||
///
|
///
|
||||||
/// Fails, if one of the operators in the expression tree fails.
|
/// Fails, if one of the operators in the expression tree fails.
|
||||||
@ -256,6 +279,13 @@ impl Node {
|
|||||||
self.eval_tuple_with_context(&EmptyContext)
|
self.eval_tuple_with_context(&EmptyContext)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Evaluates the operator tree rooted at this node into an empty value with an empty context.
|
||||||
|
///
|
||||||
|
/// Fails, if one of the operators in the expression tree fails.
|
||||||
|
pub fn eval_empty(&self) -> EvalexprResult<EmptyType> {
|
||||||
|
self.eval_empty_with_context(&EmptyContext)
|
||||||
|
}
|
||||||
|
|
||||||
fn children(&self) -> &[Node] {
|
fn children(&self) -> &[Node] {
|
||||||
&self.children
|
&self.children
|
||||||
}
|
}
|
||||||
|
@ -15,6 +15,9 @@ pub type TupleType = Vec<Value>;
|
|||||||
/// The type used to represent empty values in `Value::Empty`.
|
/// The type used to represent empty values in `Value::Empty`.
|
||||||
pub type EmptyType = ();
|
pub type EmptyType = ();
|
||||||
|
|
||||||
|
/// The value of the empty type to be used in rust.
|
||||||
|
pub const EMPTY_VALUE: () = ();
|
||||||
|
|
||||||
/// The value type used by the parser.
|
/// The value type used by the parser.
|
||||||
/// Values can be of different subtypes that are the variants of this enum.
|
/// Values can be of different subtypes that are the variants of this enum.
|
||||||
#[derive(Clone, Debug, PartialEq)]
|
#[derive(Clone, Debug, PartialEq)]
|
||||||
|
@ -234,7 +234,17 @@ fn test_n_ary_functions() {
|
|||||||
"count".into(),
|
"count".into(),
|
||||||
Function::new(
|
Function::new(
|
||||||
None,
|
None,
|
||||||
Box::new(|arguments| Ok(Value::Int(arguments.len() as IntType))),
|
Box::new(|arguments| {
|
||||||
|
if arguments.len() == 1 {
|
||||||
|
if arguments[0] == Value::Empty {
|
||||||
|
Ok(Value::Int(0))
|
||||||
|
} else {
|
||||||
|
Ok(Value::Int(1))
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Ok(Value::Int(arguments.len() as IntType))
|
||||||
|
}
|
||||||
|
}),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
@ -259,13 +269,7 @@ fn test_n_ary_functions() {
|
|||||||
eval_with_context("muladd(3, 6, -4)", &context),
|
eval_with_context("muladd(3, 6, -4)", &context),
|
||||||
Ok(Value::Int(14))
|
Ok(Value::Int(14))
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(eval_with_context("count()", &context), Ok(Value::Int(0)));
|
||||||
eval_with_context("count()", &context),
|
|
||||||
Err(EvalexprError::WrongOperatorArgumentAmount {
|
|
||||||
actual: 0,
|
|
||||||
expected: 1
|
|
||||||
})
|
|
||||||
);
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
eval_with_context("count(3, 5.5, 2)", &context),
|
eval_with_context("count(3, 5.5, 2)", &context),
|
||||||
Ok(Value::Int(3))
|
Ok(Value::Int(3))
|
||||||
@ -407,6 +411,12 @@ fn test_shortcut_functions() {
|
|||||||
.eval_tuple_with_context(&context),
|
.eval_tuple_with_context(&context),
|
||||||
Ok(vec![Value::Int(3), Value::Int(3)])
|
Ok(vec![Value::Int(3), Value::Int(3)])
|
||||||
);
|
);
|
||||||
|
assert_eq!(
|
||||||
|
build_operator_tree("")
|
||||||
|
.unwrap()
|
||||||
|
.eval_empty_with_context(&context),
|
||||||
|
Ok(EMPTY_VALUE)
|
||||||
|
);
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
eval_string_with_context_mut("string", &mut context),
|
eval_string_with_context_mut("string", &mut context),
|
||||||
@ -458,9 +468,20 @@ fn test_shortcut_functions() {
|
|||||||
assert_eq!(
|
assert_eq!(
|
||||||
build_operator_tree("3,3")
|
build_operator_tree("3,3")
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.eval_tuple_with_context(&mut context),
|
.eval_tuple_with_context_mut(&mut context),
|
||||||
Ok(vec![Value::Int(3), Value::Int(3)])
|
Ok(vec![Value::Int(3), Value::Int(3)])
|
||||||
);
|
);
|
||||||
|
assert_eq!(
|
||||||
|
build_operator_tree("")
|
||||||
|
.unwrap()
|
||||||
|
.eval_empty_with_context_mut(&mut context),
|
||||||
|
Ok(EMPTY_VALUE)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_whitespace() {
|
||||||
|
assert!(eval_boolean("2 < = 3").is_err());
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "serde")]
|
#[cfg(feature = "serde")]
|
||||||
|
Loading…
Reference in New Issue
Block a user