Add Scope::is_constant.

This commit is contained in:
Stephen Chung 2021-08-13 22:47:03 +08:00
parent 114c93f430
commit 0354f154ce
3 changed files with 31 additions and 7 deletions

View File

@ -22,6 +22,7 @@ Enhancements
* Added `log10()` for `Decimal`. * Added `log10()` for `Decimal`.
* `ln` for `Decimal` is now checked and won't panic. * `ln` for `Decimal` is now checked and won't panic.
* `Scope::set_value` now takes anything that implements `Into<Cow<str>>`. * `Scope::set_value` now takes anything that implements `Into<Cow<str>>`.
* Added `Scope::is_constant` to check if a variable is constant.
Version 1.0.2 Version 1.0.2

View File

@ -339,6 +339,30 @@ impl<'a> Scope<'a> {
.find(|(_, (key, _))| name == key.as_ref()) .find(|(_, (key, _))| name == key.as_ref())
.and_then(|(index, _)| self.values[index].flatten_clone().try_cast()) .and_then(|(index, _)| self.values[index].flatten_clone().try_cast())
} }
/// Check if the named entry in the [`Scope`] is constant.
///
/// Search starts backwards from the last, stopping at the first entry matching the specified name.
///
/// Returns [`None`] if no entry matching the specified name is found.
///
/// # Example
///
/// ```
/// use rhai::Scope;
///
/// let mut my_scope = Scope::new();
///
/// my_scope.push_constant("x", 42_i64);
/// assert_eq!(my_scope.is_constant("x"), Some(true));
/// assert_eq!(my_scope.is_constant("y"), None);
/// ```
#[inline]
pub fn is_constant(&self, name: &str) -> Option<bool> {
self.get_index(name).and_then(|(_, access)| match access {
AccessMode::ReadWrite => None,
AccessMode::ReadOnly => Some(true),
})
}
/// Update the value of the named entry in the [`Scope`]. /// Update the value of the named entry in the [`Scope`].
/// ///
/// Search starts backwards from the last, and only the first entry matching the specified name is updated. /// Search starts backwards from the last, and only the first entry matching the specified name is updated.

View File

@ -157,13 +157,12 @@ fn test_custom_syntax() -> Result<(), Box<EvalAltResult>> {
// Evaluate the expression // Evaluate the expression
let value = context.eval_expression_tree(expr)?; let value = context.eval_expression_tree(expr)?;
// Push new variable into the scope if it doesn't already exist. if !context.scope().is_constant(&var_name).unwrap_or(false) {
// Otherwise set its value.
// WARNING - This panics if 'var_name' already exists and is constant!
// - In a real implementation, check this before doing anything!
context.scope_mut().set_value(var_name, value); context.scope_mut().set_value(var_name, value);
Ok(Dynamic::UNIT) Ok(Dynamic::UNIT)
} else {
Err(format!("variable {} is constant", var_name).into())
}
}, },
)?; )?;