From f307b436f5fc2760781e6eb541369f05f496573f Mon Sep 17 00:00:00 2001 From: Jeff Date: Wed, 23 Aug 2023 22:03:26 -0400 Subject: [PATCH] Implement nested cross-type dot notation --- src/value/variable_map.rs | 50 ++++++++++++++++++--------------------- 1 file changed, 23 insertions(+), 27 deletions(-) diff --git a/src/value/variable_map.rs b/src/value/variable_map.rs index 6595401..ce3260b 100644 --- a/src/value/variable_map.rs +++ b/src/value/variable_map.rs @@ -54,39 +54,35 @@ impl VariableMap { } pub fn get_value(&self, identifier: &str) -> Result> { - let split = identifier.split_once('.'); - - 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 if let Value::List(list) = value { - let index = if let Ok(index) = next_identifier.parse::() { - index - } else { - return Err(Error::ExpectedInt { - actual: Value::String(next_identifier.to_string()), - }); - }; - let value = list.get(index); - - Ok(value.cloned()) - } else { - Err(Error::ExpectedMap { - actual: value.clone(), - }) - } + 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 { - Ok(None) + (self.variables.get(identifier).cloned(), next_identifier) } } else { - let value = self.variables.get(identifier); + return Ok(self.variables.get(identifier).cloned()); + }; - if let Some(value) = value { - Ok(Some(value.clone())) + if let Some(value) = found_value { + if let Value::List(list) = value { + let index = if let Ok(index) = next_identifier.parse::() { + index + } else { + return Err(Error::expected_int(Value::String( + next_identifier.to_string(), + ))); + }; + + Ok(list.get(index).cloned()) + } else if let Value::Map(map) = value { + map.get_value(next_identifier) } else { - Ok(None) + Ok(Some(value)) } + } else { + Ok(None) } }