diff --git a/src/abstract_tree/for.rs b/src/abstract_tree/for.rs index a3f19eb..e2295c8 100644 --- a/src/abstract_tree/for.rs +++ b/src/abstract_tree/for.rs @@ -78,13 +78,13 @@ impl AbstractTree for For { }; let key = self.item_id.clone(); - self.context.inherit_from(context)?; + self.context.inherit_all_from(context)?; self.context.set_type(key, item_type)?; self.block.validate(_source, &self.context) } fn run(&self, source: &str, context: &Context) -> Result { - self.context.inherit_from(context)?; + self.context.inherit_all_from(context)?; let expression_run = self.collection.run(source, context)?; let key = &self.item_id; diff --git a/src/context.rs b/src/context.rs index 14f98af..9d25c24 100644 --- a/src/context.rs +++ b/src/context.rs @@ -117,6 +117,35 @@ impl Context { Ok(()) } + /// Modify a context to take the functions and type definitions of another. + /// + /// In the case of the conflict, the inherited value will override the previous + /// value. + /// + /// ``` + /// # use dust_lang::*; + /// let first_context = Context::new(); + /// let second_context = Context::new(); + /// + /// second_context.set_value( + /// "Foo".into(), + /// Value::String("Bar".to_string()) + /// ); + /// + /// first_context.inherit_from(&second_context).unwrap(); + /// + /// assert_eq!(first_context, second_context); + /// ``` + pub fn inherit_all_from(&self, other: &Context) -> Result<(), RwLockError> { + let mut self_variables = self.inner.write()?; + + for (identifier, value_data) in other.inner.read()?.iter() { + self_variables.insert(identifier.clone(), value_data.clone()); + } + + Ok(()) + } + /// Get a value from the context. /// /// This will also return a built-in value if one matches the key. See the