Fix calling functions without arguments
This commit is contained in:
parent
da7d52caef
commit
e730028185
@ -5,6 +5,7 @@
|
||||
//! 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.
|
||||
|
||||
use std::{
|
||||
cell::Cell,
|
||||
collections::BTreeMap,
|
||||
fmt::Display,
|
||||
fs,
|
||||
@ -25,7 +26,7 @@ mod predefined;
|
||||
/// An immutable context.
|
||||
pub trait Context {
|
||||
/// Returns the value that is linked to the given identifier.
|
||||
fn get_value(&self, identifier: &str) -> Option<&Value>;
|
||||
fn get_value(&self, identifier: &str) -> EvalexprResult<Option<Value>>;
|
||||
|
||||
/// Calls the function that is linked to the given identifier with the given argument.
|
||||
/// If no function with the given identifier is found, this method returns `EvalexprError::FunctionIdentifierNotFound`.
|
||||
@ -49,7 +50,7 @@ pub trait ContextWithMutableFunctions: Context {
|
||||
}
|
||||
|
||||
/// A context that stores its mappings in hash maps.
|
||||
#[derive(Clone, Debug, Default)]
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct VariableMap {
|
||||
variables: BTreeMap<String, Value>,
|
||||
}
|
||||
@ -87,25 +88,36 @@ impl PartialEq for VariableMap {
|
||||
impl VariableMap {
|
||||
/// Create a new instace.
|
||||
pub fn new() -> Self {
|
||||
Default::default()
|
||||
VariableMap {
|
||||
variables: BTreeMap::new(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Context for VariableMap {
|
||||
fn get_value(&self, identifier: &str) -> Option<&Value> {
|
||||
fn get_value(&self, identifier: &str) -> EvalexprResult<Option<Value>> {
|
||||
let split = identifier.split_once(".");
|
||||
if let Some((map_name, next_identifier)) = split {
|
||||
let value = self.variables.get(map_name)?;
|
||||
if let Some((identifier, next_identifier)) = split {
|
||||
if let Some(value) = self.variables.get(identifier) {
|
||||
if let Value::Map(map) = value {
|
||||
map.get_value(next_identifier)
|
||||
} else {
|
||||
None
|
||||
Err(EvalexprError::ExpectedMap {
|
||||
actual: value.clone(),
|
||||
})
|
||||
}
|
||||
} else {
|
||||
self.variables.get(identifier).or_else(|| {
|
||||
self.call_function(identifier, &Value::Empty);
|
||||
None
|
||||
})
|
||||
Ok(None)
|
||||
}
|
||||
} else {
|
||||
let value = self.variables.get(identifier);
|
||||
|
||||
if let Some(value) = value {
|
||||
Ok(Some(value.clone()))
|
||||
} else {
|
||||
self.call_function(identifier, &Value::Empty)
|
||||
.map(|value| Some(value))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -119,7 +131,9 @@ impl ContextWithMutableVariables for VariableMap {
|
||||
let split = identifier.split_once(".");
|
||||
|
||||
if let Some((map_name, next_identifier)) = split {
|
||||
if let Some(map_value) = self.variables.get_mut(map_name) {
|
||||
let get_value = self.variables.get_mut(map_name);
|
||||
|
||||
if let Some(map_value) = get_value {
|
||||
if let Value::Map(map) = map_value {
|
||||
map.set_value(next_identifier, value)
|
||||
} else {
|
||||
@ -128,11 +142,10 @@ impl ContextWithMutableVariables for VariableMap {
|
||||
});
|
||||
}
|
||||
} else {
|
||||
let mut new_map = VariableMap {
|
||||
variables: BTreeMap::new(),
|
||||
};
|
||||
let mut new_map = VariableMap::new();
|
||||
|
||||
new_map.set_value(next_identifier, value)?;
|
||||
|
||||
self.variables
|
||||
.insert(map_name.to_string(), Value::Map(new_map));
|
||||
|
||||
|
@ -446,7 +446,7 @@ impl Operator {
|
||||
VariableIdentifierRead { identifier } => {
|
||||
expect_operator_argument_amount(arguments.len(), 0)?;
|
||||
|
||||
if let Some(value) = context.get_value(identifier).cloned() {
|
||||
if let Some(value) = context.get_value(identifier)? {
|
||||
Ok(value)
|
||||
} else {
|
||||
Err(EvalexprError::VariableIdentifierNotFound(
|
||||
|
Loading…
Reference in New Issue
Block a user