Implement standard traits for Imports.

This commit is contained in:
Stephen Chung 2021-07-04 16:33:26 +08:00
parent ab21ba703f
commit 23cc48f937

View File

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