diff --git a/src/engine.rs b/src/engine.rs index fc6c1b44..cfe0e843 100644 --- a/src/engine.rs +++ b/src/engine.rs @@ -24,6 +24,7 @@ use std::{ collections::{BTreeMap, BTreeSet}, fmt, hash::{Hash, Hasher}, + iter::{FromIterator, Rev, Zip}, num::{NonZeroU8, NonZeroUsize}, ops::{Deref, DerefMut}, }; @@ -62,6 +63,12 @@ pub struct Imports { } impl Imports { + /// Create a new stack of imported [modules][Module]. + #[inline(always)] + #[must_use] + pub fn new() -> Self { + Default::default() + } /// Get the length of this stack of imported [modules][Module]. #[inline(always)] #[must_use] @@ -74,20 +81,20 @@ impl Imports { pub fn is_empty(&self) -> bool { self.keys.is_empty() } - /// Get the imported [modules][Module] at a particular index. + /// Get the imported [module][Module] at a particular index. #[inline(always)] #[must_use] pub fn get(&self, index: usize) -> Option> { self.modules.get(index).cloned() } - /// Get the imported [modules][Module] at a particular index. + /// Get the imported [module][Module] at a particular index. #[allow(dead_code)] #[inline(always)] #[must_use] pub(crate) fn get_mut(&mut self, index: usize) -> Option<&mut Shared> { self.modules.get_mut(index) } - /// Get the index of an imported [modules][Module] by name. + /// Get the index of an imported [module][Module] by name. #[inline(always)] #[must_use] pub fn find(&self, name: &str) -> Option { @@ -97,7 +104,7 @@ impl Imports { .rev() .find_map(|(i, key)| if key == name { Some(i) } else { None }) } - /// Push an imported [modules][Module] onto the stack. + /// Push an imported [module][Module] onto the stack. #[inline(always)] pub fn push(&mut self, name: impl Into, module: impl Into>) { self.keys.push(name.into()); @@ -134,15 +141,6 @@ impl Imports { pub(crate) fn scan_raw(&self) -> impl Iterator)> { self.keys.iter().zip(self.modules.iter()) } - /// Get a consuming iterator to this stack of imported [modules][Module] in reverse order. - #[inline(always)] - #[must_use] - pub fn into_iter(self) -> impl Iterator)> { - self.keys - .into_iter() - .rev() - .zip(self.modules.into_iter().rev()) - } /// Does the specified function hash key exist in this stack of imported [modules][Module]? #[allow(dead_code)] #[inline(always)] @@ -150,7 +148,7 @@ impl Imports { pub fn contains_fn(&self, hash: u64) -> bool { self.modules.iter().any(|m| m.contains_qualified_fn(hash)) } - /// Get specified function via its hash key. + /// Get the specified function via its hash key from this stack of imported [modules][Module]. #[inline(always)] #[must_use] pub fn get_fn(&self, hash: u64) -> Option<(&CallableFunction, Option<&Identifier>)> { @@ -167,7 +165,8 @@ impl Imports { pub fn contains_iter(&self, id: TypeId) -> bool { self.modules.iter().any(|m| m.contains_qualified_iter(id)) } - /// Get the specified [`TypeId`][std::any::TypeId] iterator. + /// Get the specified [`TypeId`][std::any::TypeId] iterator from this stack of imported + /// [modules][Module]. #[inline(always)] #[must_use] pub fn get_iter(&self, id: TypeId) -> Option { @@ -178,6 +177,37 @@ impl Imports { } } +impl IntoIterator for Imports { + type Item = (Identifier, Shared); + type IntoIter = + Zip>, Rev; 4]>>>; + + #[inline(always)] + fn into_iter(self) -> Self::IntoIter { + self.keys + .into_iter() + .rev() + .zip(self.modules.into_iter().rev()) + } +} + +impl, M: Into>> FromIterator<(K, M)> for Imports { + fn from_iter>(iter: T) -> Self { + let mut lib = Self::new(); + lib.extend(iter); + lib + } +} + +impl, M: Into>> Extend<(K, M)> for Imports { + fn extend>(&mut self, iter: T) { + iter.into_iter().for_each(|(k, m)| { + self.keys.push(k.into()); + self.modules.push(m.into()); + }) + } +} + impl fmt::Debug for Imports { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.write_str("Imports")?;