Add shortcut functions for evaluating directly into a value type
+ Added shortcut functions `eval_[type]` and `eval_[type]_with_configuration` for each value type + Added integration tests for the above Partially implements #15
This commit is contained in:
parent
5549f1bba5
commit
2dac0576a7
@ -4,7 +4,9 @@
|
|||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|
||||||
* Made internal alias `IntType` and `FloatType` used by the `Value` enum public
|
* Internal alias `IntType` and `FloatType` used by the `Value` enum are now public
|
||||||
|
* Error types for expecting each value type
|
||||||
|
* Shortcut functions like `eval_int` to evaluate directly into a value type
|
||||||
|
|
||||||
### Removed
|
### Removed
|
||||||
|
|
||||||
|
@ -27,6 +27,12 @@ pub enum Error {
|
|||||||
actual: usize,
|
actual: usize,
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/// A string value was expected.
|
||||||
|
ExpectedString {
|
||||||
|
/// The actual value.
|
||||||
|
actual: Value,
|
||||||
|
},
|
||||||
|
|
||||||
/// An integer value was expected.
|
/// An integer value was expected.
|
||||||
ExpectedInt {
|
ExpectedInt {
|
||||||
/// The actual value.
|
/// The actual value.
|
||||||
@ -52,6 +58,12 @@ pub enum Error {
|
|||||||
actual: Value,
|
actual: Value,
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/// A tuple value was expected.
|
||||||
|
ExpectedTuple {
|
||||||
|
/// The actual value.
|
||||||
|
actual: Value,
|
||||||
|
},
|
||||||
|
|
||||||
/// The given expression is empty
|
/// The given expression is empty
|
||||||
EmptyExpression,
|
EmptyExpression,
|
||||||
|
|
||||||
@ -158,6 +170,11 @@ impl Error {
|
|||||||
Error::TypeError { actual, expected }
|
Error::TypeError { actual, expected }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Constructs `Error::ExpectedString(actual)`.
|
||||||
|
pub fn expected_string(actual: Value) -> Self {
|
||||||
|
Error::ExpectedString { actual }
|
||||||
|
}
|
||||||
|
|
||||||
/// Constructs `Error::ExpectedInt(actual)`.
|
/// Constructs `Error::ExpectedInt(actual)`.
|
||||||
pub fn expected_int(actual: Value) -> Self {
|
pub fn expected_int(actual: Value) -> Self {
|
||||||
Error::ExpectedInt { actual }
|
Error::ExpectedInt { actual }
|
||||||
@ -178,6 +195,11 @@ impl Error {
|
|||||||
Error::ExpectedBoolean { actual }
|
Error::ExpectedBoolean { actual }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Constructs `Error::ExpectedTuple(actual)`.
|
||||||
|
pub fn expected_tuple(actual: Value) -> Self {
|
||||||
|
Error::ExpectedTuple { actual }
|
||||||
|
}
|
||||||
|
|
||||||
pub(crate) fn unmatched_partial_token(
|
pub(crate) fn unmatched_partial_token(
|
||||||
first: PartialToken,
|
first: PartialToken,
|
||||||
second: Option<PartialToken>,
|
second: Option<PartialToken>,
|
||||||
|
@ -3,6 +3,8 @@ use tree;
|
|||||||
use Configuration;
|
use Configuration;
|
||||||
use EmptyConfiguration;
|
use EmptyConfiguration;
|
||||||
use Error;
|
use Error;
|
||||||
|
use FloatType;
|
||||||
|
use IntType;
|
||||||
use Node;
|
use Node;
|
||||||
use Value;
|
use Value;
|
||||||
|
|
||||||
@ -70,3 +72,128 @@ pub fn eval_with_configuration(
|
|||||||
pub fn build_operator_tree(string: &str) -> Result<Node, Error> {
|
pub fn build_operator_tree(string: &str) -> Result<Node, Error> {
|
||||||
tree::tokens_to_operator_tree(token::tokenize(string)?)
|
tree::tokens_to_operator_tree(token::tokenize(string)?)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Evaluate the given expression string expecting a string.
|
||||||
|
///
|
||||||
|
/// *See the [crate doc](index.html) for more examples and explanations of the expression format.*
|
||||||
|
pub fn eval_string(string: &str) -> Result<String, Error> {
|
||||||
|
match eval(string) {
|
||||||
|
Ok(Value::String(string)) => Ok(string),
|
||||||
|
Ok(value) => Err(Error::expected_string(value)),
|
||||||
|
Err(error) => Err(error),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Evaluate the given expression string expecting an integer.
|
||||||
|
///
|
||||||
|
/// *See the [crate doc](index.html) for more examples and explanations of the expression format.*
|
||||||
|
pub fn eval_int(string: &str) -> Result<IntType, Error> {
|
||||||
|
match eval(string) {
|
||||||
|
Ok(Value::Int(int)) => Ok(int),
|
||||||
|
Ok(value) => Err(Error::expected_int(value)),
|
||||||
|
Err(error) => Err(error),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Evaluate the given expression string expecting a float.
|
||||||
|
///
|
||||||
|
/// *See the [crate doc](index.html) for more examples and explanations of the expression format.*
|
||||||
|
pub fn eval_float(string: &str) -> Result<FloatType, Error> {
|
||||||
|
match eval(string) {
|
||||||
|
Ok(Value::Float(float)) => Ok(float),
|
||||||
|
Ok(value) => Err(Error::expected_float(value)),
|
||||||
|
Err(error) => Err(error),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Evaluate the given expression string expecting a boolean.
|
||||||
|
///
|
||||||
|
/// *See the [crate doc](index.html) for more examples and explanations of the expression format.*
|
||||||
|
pub fn eval_boolean(string: &str) -> Result<bool, Error> {
|
||||||
|
match eval(string) {
|
||||||
|
Ok(Value::Boolean(boolean)) => Ok(boolean),
|
||||||
|
Ok(value) => Err(Error::expected_boolean(value)),
|
||||||
|
Err(error) => Err(error),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Evaluate the given expression string expecting a tuple.
|
||||||
|
///
|
||||||
|
/// *See the [crate doc](index.html) for more examples and explanations of the expression format.*
|
||||||
|
pub fn eval_tuple(string: &str) -> Result<Vec<Value>, Error> {
|
||||||
|
match eval(string) {
|
||||||
|
Ok(Value::Tuple(tuple)) => Ok(tuple),
|
||||||
|
Ok(value) => Err(Error::expected_tuple(value)),
|
||||||
|
Err(error) => Err(error),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Evaluate the given expression string expecting a string with the given configuration.
|
||||||
|
///
|
||||||
|
/// *See the [crate doc](index.html) for more examples and explanations of the expression format.*
|
||||||
|
pub fn eval_string_with_configuration(
|
||||||
|
string: &str,
|
||||||
|
configuration: &Configuration,
|
||||||
|
) -> Result<String, Error> {
|
||||||
|
match eval_with_configuration(string, configuration) {
|
||||||
|
Ok(Value::String(string)) => Ok(string),
|
||||||
|
Ok(value) => Err(Error::expected_string(value)),
|
||||||
|
Err(error) => Err(error),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Evaluate the given expression string expecting an integer with the given configuration.
|
||||||
|
///
|
||||||
|
/// *See the [crate doc](index.html) for more examples and explanations of the expression format.*
|
||||||
|
pub fn eval_int_with_configuration(
|
||||||
|
string: &str,
|
||||||
|
configuration: &Configuration,
|
||||||
|
) -> Result<IntType, Error> {
|
||||||
|
match eval_with_configuration(string, configuration) {
|
||||||
|
Ok(Value::Int(int)) => Ok(int),
|
||||||
|
Ok(value) => Err(Error::expected_int(value)),
|
||||||
|
Err(error) => Err(error),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Evaluate the given expression string expecting a float with the given configuration.
|
||||||
|
///
|
||||||
|
/// *See the [crate doc](index.html) for more examples and explanations of the expression format.*
|
||||||
|
pub fn eval_float_with_configuration(
|
||||||
|
string: &str,
|
||||||
|
configuration: &Configuration,
|
||||||
|
) -> Result<FloatType, Error> {
|
||||||
|
match eval_with_configuration(string, configuration) {
|
||||||
|
Ok(Value::Float(float)) => Ok(float),
|
||||||
|
Ok(value) => Err(Error::expected_float(value)),
|
||||||
|
Err(error) => Err(error),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Evaluate the given expression string expecting a boolean with the given configuration.
|
||||||
|
///
|
||||||
|
/// *See the [crate doc](index.html) for more examples and explanations of the expression format.*
|
||||||
|
pub fn eval_boolean_with_configuration(
|
||||||
|
string: &str,
|
||||||
|
configuration: &Configuration,
|
||||||
|
) -> Result<bool, Error> {
|
||||||
|
match eval_with_configuration(string, configuration) {
|
||||||
|
Ok(Value::Boolean(boolean)) => Ok(boolean),
|
||||||
|
Ok(value) => Err(Error::expected_boolean(value)),
|
||||||
|
Err(error) => Err(error),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Evaluate the given expression string expecting a tuple with the given configuration.
|
||||||
|
///
|
||||||
|
/// *See the [crate doc](index.html) for more examples and explanations of the expression format.*
|
||||||
|
pub fn eval_tuple_with_configuration(
|
||||||
|
string: &str,
|
||||||
|
configuration: &Configuration,
|
||||||
|
) -> Result<Vec<Value>, Error> {
|
||||||
|
match eval_with_configuration(string, configuration) {
|
||||||
|
Ok(Value::Tuple(tuple)) => Ok(tuple),
|
||||||
|
Ok(value) => Err(Error::expected_tuple(value)),
|
||||||
|
Err(error) => Err(error),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -336,3 +336,32 @@ fn test_no_panic() {
|
|||||||
))
|
))
|
||||||
.is_ok());
|
.is_ok());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_shortcut_functions() {
|
||||||
|
let mut configuration = HashMapConfiguration::new();
|
||||||
|
configuration.insert_variable("string", Value::from("a string"));
|
||||||
|
|
||||||
|
// assert_eq!(eval_string("???"));
|
||||||
|
assert_eq!(
|
||||||
|
eval_string_with_configuration("string", &configuration),
|
||||||
|
Ok("a string".to_string())
|
||||||
|
);
|
||||||
|
assert_eq!(eval_float("3.3"), Ok(3.3));
|
||||||
|
assert_eq!(
|
||||||
|
eval_float_with_configuration("3.3", &configuration),
|
||||||
|
Ok(3.3)
|
||||||
|
);
|
||||||
|
assert_eq!(eval_int("3"), Ok(3));
|
||||||
|
assert_eq!(eval_int_with_configuration("3", &configuration), Ok(3));
|
||||||
|
assert_eq!(eval_boolean("true"), Ok(true));
|
||||||
|
assert_eq!(
|
||||||
|
eval_boolean_with_configuration("true", &configuration),
|
||||||
|
Ok(true)
|
||||||
|
);
|
||||||
|
assert_eq!(eval_tuple("3,3"), Ok(vec![Value::Int(3), Value::Int(3)]));
|
||||||
|
assert_eq!(
|
||||||
|
eval_tuple_with_configuration("3,3", &configuration),
|
||||||
|
Ok(vec![Value::Int(3), Value::Int(3)])
|
||||||
|
);
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user