Create mutable context when using eval functions without context

While this is a tiny hit on performance, it is something that the user probably wants.
It specifically prevents the user from seeing ContextNotManipulable errors when using the full power of evalexpr in the simplest eval calls.

Implements #45
This commit is contained in:
Sebastian Schmidt 2019-08-29 09:44:14 +03:00
parent 596d4d37b1
commit 6ace829117
3 changed files with 23 additions and 13 deletions

View File

@ -1,8 +1,7 @@
use crate::token; use crate::{token, HashMapContext};
use crate::tree; use crate::tree;
use crate::value::TupleType; use crate::value::TupleType;
use crate::Context; use crate::Context;
use crate::EmptyContext;
use crate::EmptyType; use crate::EmptyType;
use crate::EvalexprError; use crate::EvalexprError;
use crate::EvalexprResult; use crate::EvalexprResult;
@ -24,7 +23,7 @@ use crate::EMPTY_VALUE;
/// ///
/// *See the [crate doc](index.html) for more examples and explanations of the expression format.* /// *See the [crate doc](index.html) for more examples and explanations of the expression format.*
pub fn eval(string: &str) -> EvalexprResult<Value> { pub fn eval(string: &str) -> EvalexprResult<Value> {
eval_with_context(string, &EmptyContext) eval_with_context_mut(string, &mut HashMapContext::new())
} }
/// Evaluate the given expression string with the given context. /// Evaluate the given expression string with the given context.
@ -97,21 +96,21 @@ pub fn build_operator_tree(string: &str) -> EvalexprResult<Node> {
/// ///
/// *See the [crate doc](index.html) for more examples and explanations of the expression format.* /// *See the [crate doc](index.html) for more examples and explanations of the expression format.*
pub fn eval_string(string: &str) -> EvalexprResult<String> { pub fn eval_string(string: &str) -> EvalexprResult<String> {
eval_string_with_context(string, &EmptyContext) eval_string_with_context_mut(string, &mut HashMapContext::new())
} }
/// Evaluate the given expression string into an integer. /// Evaluate the given expression string into an integer.
/// ///
/// *See the [crate doc](index.html) for more examples and explanations of the expression format.* /// *See the [crate doc](index.html) for more examples and explanations of the expression format.*
pub fn eval_int(string: &str) -> EvalexprResult<IntType> { pub fn eval_int(string: &str) -> EvalexprResult<IntType> {
eval_int_with_context(string, &EmptyContext) eval_int_with_context_mut(string, &mut HashMapContext::new())
} }
/// Evaluate the given expression string into a float. /// Evaluate the given expression string into a float.
/// ///
/// *See the [crate doc](index.html) for more examples and explanations of the expression format.* /// *See the [crate doc](index.html) for more examples and explanations of the expression format.*
pub fn eval_float(string: &str) -> EvalexprResult<FloatType> { pub fn eval_float(string: &str) -> EvalexprResult<FloatType> {
eval_float_with_context(string, &EmptyContext) eval_float_with_context_mut(string, &mut HashMapContext::new())
} }
/// Evaluate the given expression string into a float. /// Evaluate the given expression string into a float.
@ -119,28 +118,28 @@ pub fn eval_float(string: &str) -> EvalexprResult<FloatType> {
/// ///
/// *See the [crate doc](index.html) for more examples and explanations of the expression format.* /// *See the [crate doc](index.html) for more examples and explanations of the expression format.*
pub fn eval_number(string: &str) -> EvalexprResult<FloatType> { pub fn eval_number(string: &str) -> EvalexprResult<FloatType> {
eval_number_with_context(string, &EmptyContext) eval_number_with_context_mut(string, &mut HashMapContext::new())
} }
/// Evaluate the given expression string into a boolean. /// Evaluate the given expression string into a boolean.
/// ///
/// *See the [crate doc](index.html) for more examples and explanations of the expression format.* /// *See the [crate doc](index.html) for more examples and explanations of the expression format.*
pub fn eval_boolean(string: &str) -> EvalexprResult<bool> { pub fn eval_boolean(string: &str) -> EvalexprResult<bool> {
eval_boolean_with_context(string, &EmptyContext) eval_boolean_with_context_mut(string, &mut HashMapContext::new())
} }
/// Evaluate the given expression string into a tuple. /// Evaluate the given expression string into a tuple.
/// ///
/// *See the [crate doc](index.html) for more examples and explanations of the expression format.* /// *See the [crate doc](index.html) for more examples and explanations of the expression format.*
pub fn eval_tuple(string: &str) -> EvalexprResult<TupleType> { pub fn eval_tuple(string: &str) -> EvalexprResult<TupleType> {
eval_tuple_with_context(string, &EmptyContext) eval_tuple_with_context_mut(string, &mut HashMapContext::new())
} }
/// Evaluate the given expression string into an empty value. /// Evaluate the given expression string into an empty value.
/// ///
/// *See the [crate doc](index.html) for more examples and explanations of the expression format.* /// *See the [crate doc](index.html) for more examples and explanations of the expression format.*
pub fn eval_empty(string: &str) -> EvalexprResult<EmptyType> { pub fn eval_empty(string: &str) -> EvalexprResult<EmptyType> {
eval_empty_with_context(string, &EmptyContext) eval_empty_with_context_mut(string, &mut HashMapContext::new())
} }
/// Evaluate the given expression string into a string with the given context. /// Evaluate the given expression string into a string with the given context.

View File

@ -2,9 +2,6 @@ extern crate evalexpr;
use evalexpr::{error::*, *}; use evalexpr::{error::*, *};
#[cfg(feature = "serde")]
mod serde;
#[test] #[test]
fn test_unary_examples() { fn test_unary_examples() {
assert_eq!(eval("3"), Ok(Value::Int(3))); assert_eq!(eval("3"), Ok(Value::Int(3)));
@ -639,3 +636,15 @@ fn test_tuple_definitions() {
Ok(vec![Value::from(1), Value::from(2)]) Ok(vec![Value::from(1), Value::from(2)])
); );
} }
#[test]
fn test_implicit_context() {
assert_eq!(eval("a = 2 + 4 * 2; b = -5 + 3 * 5; a == b"), Ok(Value::from(true)));
assert_eq!(eval_boolean("a = 2 + 4 * 2; b = -5 + 3 * 5; a == b"), Ok(true));
assert_eq!(eval_int("a = 2 + 4 * 2; b = -5 + 3 * 5; a - b"), Ok(0));
assert_eq!(eval_float("a = 2 + 4 * 2; b = -5 + 3 * 5; a - b + 0.5"), Ok(0.5));
assert_eq!(eval_number("a = 2 + 4 * 2; b = -5 + 3 * 5; a - b"), Ok(0.0));
assert_eq!(eval_empty("a = 2 + 4 * 2; b = -5 + 3 * 5;"), Ok(()));
assert_eq!(eval_tuple("a = 2 + 4 * 2; b = -5 + 3 * 5; a, b + 0.5"), Ok(vec![Value::from(10), Value::from(10.5)]));
assert_eq!(eval_string("a = \"xyz\"; b = \"abc\"; c = a + b; c"), Ok("xyzabc".to_string()));
}

View File

@ -1,3 +1,5 @@
#![cfg(feature = "serde")]
use evalexpr::{build_operator_tree, Node}; use evalexpr::{build_operator_tree, Node};
#[test] #[test]