diff --git a/CHANGELOG.md b/CHANGELOG.md index 97aea371..e594d41e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -34,6 +34,7 @@ Enhancements * `range` function now supports negative step and decreasing streams (i.e. to < from). * More information is provided to the error variable captured by the `catch` statement in an _object map_. * Previously, `private` functions in an `AST` cannot be called with `call_fn` etc. This is inconvenient when trying to call a function inside a script which also serves as a loadable module exporting part (but not all) of the functions. Now, all functions (`private` or not) can be called in an `AST`. The `private` keyword is relegated to preventing a function from being exported. +* `Dynamic::as_unit` just for completeness sake. Version 0.19.13 diff --git a/src/dynamic.rs b/src/dynamic.rs index b0168ccb..47fe3e2d 100644 --- a/src/dynamic.rs +++ b/src/dynamic.rs @@ -134,17 +134,6 @@ pub enum AccessMode { ReadOnly, } -impl AccessMode { - /// Is the access type `ReadOnly`? - #[inline(always)] - pub fn is_read_only(self) -> bool { - match self { - Self::ReadWrite => false, - Self::ReadOnly => true, - } - } -} - /// Dynamic type containing any value. pub struct Dynamic(pub(crate) Union); @@ -748,17 +737,25 @@ impl Dynamic { pub fn is_read_only(&self) -> bool { match self.0 { #[cfg(not(feature = "no_closure"))] - Union::Shared(_, access) if access.is_read_only() => true, + Union::Shared(_, AccessMode::ReadOnly) => true, #[cfg(not(feature = "no_closure"))] - #[cfg(not(feature = "sync"))] - Union::Shared(ref cell, _) => cell.borrow().access_mode().is_read_only(), + Union::Shared(ref cell, _) => { + #[cfg(not(feature = "sync"))] + let access = cell.borrow().access_mode(); + #[cfg(feature = "sync")] + let access = cell.read().unwrap().access_mode(); - #[cfg(not(feature = "no_closure"))] - #[cfg(feature = "sync")] - Union::Shared(ref cell, _) => cell.read().unwrap().access_mode().is_read_only(), + match access { + AccessMode::ReadWrite => false, + AccessMode::ReadOnly => true, + } + } - _ => self.access_mode().is_read_only(), + _ => match self.access_mode() { + AccessMode::ReadWrite => false, + AccessMode::ReadOnly => true, + }, } } /// Can this [`Dynamic`] be hashed? @@ -1439,6 +1436,17 @@ impl Dynamic { _ => None, } } + /// Cast the [`Dynamic`] as a unit `()` and return it. + /// Returns the name of the actual type if the cast fails. + #[inline(always)] + pub fn as_unit(&self) -> Result<(), &'static str> { + match self.0 { + Union::Unit(value, _) => Ok(value), + #[cfg(not(feature = "no_closure"))] + Union::Shared(_, _) => self.read_lock().map(|v| *v).ok_or_else(|| self.type_name()), + _ => Err(self.type_name()), + } + } /// Cast the [`Dynamic`] as the system integer type [`INT`] and return it. /// Returns the name of the actual type if the cast fails. #[inline(always)] diff --git a/src/optimize.rs b/src/optimize.rs index b484e643..cff6580b 100644 --- a/src/optimize.rs +++ b/src/optimize.rs @@ -113,17 +113,16 @@ impl<'a> State<'a> { return None; } - for (n, access, expr) in self.variables.iter().rev() { + self.variables.iter().rev().find_map(|(n, access, expr)| { if n == name { - return if access.is_read_only() { - Some(expr) - } else { - None - }; + match access { + AccessMode::ReadWrite => None, + AccessMode::ReadOnly => Some(expr), + } + } else { + None } - } - - None + }) } }