Skip to content

Commit

Permalink
Add Scope::get_value_ref and get_value_mut.
Browse files Browse the repository at this point in the history
  • Loading branch information
schungx committed Nov 12, 2023
1 parent e239f32 commit 18a09ea
Show file tree
Hide file tree
Showing 3 changed files with 79 additions and 16 deletions.
2 changes: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ Enhancements
* Added `to_int` method for characters.
* `Token::FloatConstant` and `Token::DecimalConstant` now carry the original text representation for use in, say, a _token mapper_.
* `Dynamic::is_fnptr` is made a public API.

* `Scope::get_value_ref` and `Scope::get_value_mut` are added.

Version 1.16.3
==============
Expand Down
4 changes: 2 additions & 2 deletions src/types/dynamic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1480,7 +1480,7 @@ impl Dynamic {
/// Get a reference of a specific type to the [`Dynamic`].
/// Casting to [`Dynamic`] just returns a reference to it.
///
/// Returns [`None`] if the cast fails, or if the value is shared.
/// Returns [`None`] if the cast fails, or if the value is _shared_.
#[inline]
#[must_use]
pub(crate) fn downcast_ref<T: Any + Clone + ?Sized>(&self) -> Option<&T> {
Expand Down Expand Up @@ -1578,7 +1578,7 @@ impl Dynamic {
/// Get a mutable reference of a specific type to the [`Dynamic`].
/// Casting to [`Dynamic`] just returns a mutable reference to it.
///
/// Returns [`None`] if the cast fails, or if the value is shared.
/// Returns [`None`] if the cast fails, or if the value is _shared_.
#[inline]
#[must_use]
pub(crate) fn downcast_mut<T: Any + Clone + ?Sized>(&mut self) -> Option<&mut T> {
Expand Down
89 changes: 76 additions & 13 deletions src/types/scope.rs
Original file line number Diff line number Diff line change
Expand Up @@ -484,15 +484,8 @@ impl Scope<'_> {
self.names
.iter()
.rev() // Always search a Scope in reverse order
.enumerate()
.find_map(|(i, key)| {
if name == key {
let index = len - 1 - i;
Some(index)
} else {
None
}
})
.position(|key| name == key)
.map(|i| len - 1 - i)
}
/// Get the value of an entry in the [`Scope`], starting from the last.
///
Expand All @@ -514,10 +507,80 @@ impl Scope<'_> {
self.names
.iter()
.rev()
.enumerate()
.find(|(.., key)| &name == key)
.map(|(index, ..)| self.values[len - 1 - index].flatten_clone())
.and_then(Dynamic::try_cast)
.position(|key| &name == key)
.and_then(|i| self.values[len - 1 - i].flatten_clone().try_cast())
}
/// Get a reference the value of an entry in the [`Scope`], starting from the last.
///
/// # Panics
///
/// Panics if the value is _shared_.
///
/// # Example
///
/// ```
/// use rhai::Scope;
///
/// let mut my_scope = Scope::new();
///
/// my_scope.push("x", 42_i64);
///
/// let ptr = my_scope.get_value_ref::<i64>("x").expect("x should exist");
///
/// assert_eq!(*ptr, 42);
/// ```
#[inline]
#[must_use]
pub fn get_value_ref<T: Variant + Clone>(&self, name: &str) -> Option<&T> {
let len = self.len();

self.names
.iter()
.rev()
.position(|key| &name == key)
.and_then(|i| {
let v = &self.values[len - 1 - i];
#[cfg(not(feature = "no_closure"))]
assert!(!v.is_shared());
v.downcast_ref()
})
}
/// Get a mutable reference the value of an entry in the [`Scope`], starting from the last.
///
/// # Panics
///
/// Panics if the value is _shared_.
///
/// # Example
///
/// ```
/// use rhai::Scope;
///
/// let mut my_scope = Scope::new();
///
/// my_scope.push("x", 42_i64);
///
/// let ptr = my_scope.get_value_mut::<i64>("x").expect("x should exist");
///
/// *ptr = 0;
///
/// assert_eq!(my_scope.get_value::<i64>("x").expect("x should exist"), 0);
/// ```
#[inline]
#[must_use]
pub fn get_value_mut<T: Variant + Clone>(&mut self, name: &str) -> Option<&mut T> {
let len = self.len();

self.names
.iter_mut()
.rev()
.position(|key| &name == key)
.and_then(move |i| {
let v = &mut self.values[len - 1 - i];
#[cfg(not(feature = "no_closure"))]
assert!(!v.is_shared());
v.downcast_mut()
})
}
/// Check if the named entry in the [`Scope`] is constant.
///
Expand Down

0 comments on commit 18a09ea

Please sign in to comment.