Improve map type functionality

This commit is contained in:
Jeff 2023-06-23 22:47:02 -04:00
parent f2ae0d952f
commit 47cc649f8d
2 changed files with 31 additions and 12 deletions

View File

@ -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(())
}
}
}

View File

@ -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),
}
}
}