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.
|
//! 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::{
|
use std::{
|
||||||
|
cell::Cell,
|
||||||
collections::BTreeMap,
|
collections::BTreeMap,
|
||||||
fmt::Display,
|
fmt::Display,
|
||||||
fs,
|
fs,
|
||||||
@ -25,7 +26,7 @@ mod predefined;
|
|||||||
/// An immutable context.
|
/// An immutable context.
|
||||||
pub trait Context {
|
pub trait Context {
|
||||||
/// Returns the value that is linked to the given identifier.
|
/// 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.
|
/// 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`.
|
/// 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.
|
/// A context that stores its mappings in hash maps.
|
||||||
#[derive(Clone, Debug, Default)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct VariableMap {
|
pub struct VariableMap {
|
||||||
variables: BTreeMap<String, Value>,
|
variables: BTreeMap<String, Value>,
|
||||||
}
|
}
|
||||||
@ -87,25 +88,36 @@ impl PartialEq for VariableMap {
|
|||||||
impl VariableMap {
|
impl VariableMap {
|
||||||
/// Create a new instace.
|
/// Create a new instace.
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
Default::default()
|
VariableMap {
|
||||||
|
variables: BTreeMap::new(),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Context for VariableMap {
|
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(".");
|
let split = identifier.split_once(".");
|
||||||
if let Some((map_name, next_identifier)) = split {
|
if let Some((identifier, next_identifier)) = split {
|
||||||
let value = self.variables.get(map_name)?;
|
if let Some(value) = self.variables.get(identifier) {
|
||||||
if let Value::Map(map) = value {
|
if let Value::Map(map) = value {
|
||||||
map.get_value(next_identifier)
|
map.get_value(next_identifier)
|
||||||
|
} else {
|
||||||
|
Err(EvalexprError::ExpectedMap {
|
||||||
|
actual: value.clone(),
|
||||||
|
})
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
None
|
Ok(None)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
self.variables.get(identifier).or_else(|| {
|
let value = self.variables.get(identifier);
|
||||||
self.call_function(identifier, &Value::Empty);
|
|
||||||
None
|
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(".");
|
let split = identifier.split_once(".");
|
||||||
|
|
||||||
if let Some((map_name, next_identifier)) = split {
|
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 {
|
if let Value::Map(map) = map_value {
|
||||||
map.set_value(next_identifier, value)
|
map.set_value(next_identifier, value)
|
||||||
} else {
|
} else {
|
||||||
@ -128,11 +142,10 @@ impl ContextWithMutableVariables for VariableMap {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
let mut new_map = VariableMap {
|
let mut new_map = VariableMap::new();
|
||||||
variables: BTreeMap::new(),
|
|
||||||
};
|
|
||||||
|
|
||||||
new_map.set_value(next_identifier, value)?;
|
new_map.set_value(next_identifier, value)?;
|
||||||
|
|
||||||
self.variables
|
self.variables
|
||||||
.insert(map_name.to_string(), Value::Map(new_map));
|
.insert(map_name.to_string(), Value::Map(new_map));
|
||||||
|
|
||||||
|
@ -446,7 +446,7 @@ impl Operator {
|
|||||||
VariableIdentifierRead { identifier } => {
|
VariableIdentifierRead { identifier } => {
|
||||||
expect_operator_argument_amount(arguments.len(), 0)?;
|
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)
|
Ok(value)
|
||||||
} else {
|
} else {
|
||||||
Err(EvalexprError::VariableIdentifierNotFound(
|
Err(EvalexprError::VariableIdentifierNotFound(
|
||||||
|
Loading…
Reference in New Issue
Block a user