Improve map type functionality
This commit is contained in:
parent
f2ae0d952f
commit
47cc649f8d
@ -4,7 +4,7 @@
|
||||
//! This crate implements two basic variants, the `EmptyContext`, that returns `None` for each identifier and cannot be manipulated, and the `HashMapContext`, that stores its mappings in hash maps.
|
||||
//! 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::collections::BTreeMap;
|
||||
use std::{collections::BTreeMap, fmt::Display};
|
||||
|
||||
use crate::{
|
||||
function::Function,
|
||||
@ -46,6 +46,18 @@ pub struct VariableMap {
|
||||
variables: BTreeMap<String, Value>,
|
||||
}
|
||||
|
||||
impl Display for VariableMap {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
write!(f, "(")?;
|
||||
|
||||
for (key, value) in &self.variables {
|
||||
write!(f, " {} = {};", key, value)?;
|
||||
}
|
||||
|
||||
write!(f, " )")
|
||||
}
|
||||
}
|
||||
|
||||
impl PartialEq for VariableMap {
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
if self.variables.len() != other.variables.len() {
|
||||
@ -85,30 +97,37 @@ impl Context for VariableMap {
|
||||
|
||||
impl ContextWithMutableVariables for VariableMap {
|
||||
fn set_value(&mut self, identifier: &str, value: Value) -> EvalexprResult<()> {
|
||||
println!("{:#?}", self);
|
||||
println!("{}", identifier);
|
||||
|
||||
let split = identifier.split_once(".");
|
||||
|
||||
if let Some((map_name, next_identifier)) = split {
|
||||
if let Some(map_value) = self.variables.get_mut(map_name) {
|
||||
if let Value::Map(map) = map_value {
|
||||
map.set_value(next_identifier, value)?;
|
||||
map.set_value(next_identifier, value)
|
||||
} else {
|
||||
return Err(EvalexprError::ExpectedMap {
|
||||
actual: map_value.clone(),
|
||||
});
|
||||
}
|
||||
} else {
|
||||
let mut new_map = BTreeMap::new();
|
||||
new_map.insert(next_identifier.to_string(), value);
|
||||
let map_var = Value::Map(VariableMap { variables: new_map });
|
||||
self.variables.insert(map_name.to_string(), map_var);
|
||||
let mut new_map = VariableMap {
|
||||
variables: BTreeMap::new(),
|
||||
};
|
||||
|
||||
new_map.set_value(next_identifier, value)?;
|
||||
self.variables
|
||||
.insert(map_name.to_string(), Value::Map(new_map));
|
||||
|
||||
Ok(())
|
||||
}
|
||||
} else if self.variables.contains_key(identifier) {
|
||||
Err(EvalexprError::ExpectedMap {
|
||||
actual: value.clone(),
|
||||
})
|
||||
} else {
|
||||
self.variables.insert(identifier.to_string(), value);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -23,7 +23,7 @@ impl Display for Value {
|
||||
write!(f, ")")
|
||||
},
|
||||
Value::Empty => write!(f, "()"),
|
||||
Value::Map(_) => write!(f, "{:?}", self),
|
||||
Value::Map(map) => write!(f, "{}", map),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user