Implement nested cross-type dot notation

This commit is contained in:
Jeff 2023-08-23 22:03:26 -04:00
parent fde899bf3e
commit f307b436f5

View File

@ -54,40 +54,36 @@ impl VariableMap {
} }
pub fn get_value(&self, identifier: &str) -> Result<Option<Value>> { pub fn get_value(&self, identifier: &str) -> Result<Option<Value>> {
let split = identifier.split_once('.'); let split = identifier.rsplit_once('.');
let (found_value, next_identifier) = if let Some((identifier, next_identifier)) = split {
if identifier.contains('.') {
(self.get_value(identifier)?, next_identifier)
} else {
(self.variables.get(identifier).cloned(), next_identifier)
}
} else {
return Ok(self.variables.get(identifier).cloned());
};
if let Some((identifier, next_identifier)) = split { if let Some(value) = found_value {
if let Some(value) = self.variables.get(identifier) { if let Value::List(list) = value {
if let Value::Map(map) = value {
map.get_value(next_identifier)
} else if let Value::List(list) = value {
let index = if let Ok(index) = next_identifier.parse::<usize>() { let index = if let Ok(index) = next_identifier.parse::<usize>() {
index index
} else { } else {
return Err(Error::ExpectedInt { return Err(Error::expected_int(Value::String(
actual: Value::String(next_identifier.to_string()), next_identifier.to_string(),
}); )));
}; };
let value = list.get(index);
Ok(value.cloned()) Ok(list.get(index).cloned())
} else if let Value::Map(map) = value {
map.get_value(next_identifier)
} else { } else {
Err(Error::ExpectedMap { Ok(Some(value))
actual: value.clone(),
})
} }
} else { } else {
Ok(None) Ok(None)
} }
} else {
let value = self.variables.get(identifier);
if let Some(value) = value {
Ok(Some(value.clone()))
} else {
Ok(None)
}
}
} }
pub fn set_value(&mut self, identifier: &str, value: Value) -> Result<()> { pub fn set_value(&mut self, identifier: &str, value: Value) -> Result<()> {