use crate::{Engine, Module, ModuleResolver, Position, RhaiResultOf, Shared, ERR};
#[cfg(feature = "no_std")]
use std::prelude::v1::*;
use std::{ops::AddAssign, slice::Iter, vec::IntoIter};
#[derive(Default)]
pub struct ModuleResolversCollection(Vec<Box<dyn ModuleResolver>>);
impl ModuleResolversCollection {
#[inline(always)]
#[must_use]
pub fn new() -> Self {
Self(Vec::new())
}
#[inline(always)]
pub fn push(&mut self, resolver: impl ModuleResolver + 'static) -> &mut Self {
self.0.push(Box::new(resolver));
self
}
#[inline(always)]
pub fn insert(&mut self, index: usize, resolver: impl ModuleResolver + 'static) -> &mut Self {
self.0.insert(index, Box::new(resolver));
self
}
#[inline(always)]
pub fn pop(&mut self) -> Option<Box<dyn ModuleResolver>> {
self.0.pop()
}
#[inline(always)]
pub fn remove(&mut self, index: usize) -> Box<dyn ModuleResolver> {
self.0.remove(index)
}
#[inline]
pub fn iter(&self) -> impl Iterator<Item = &dyn ModuleResolver> {
self.0.iter().map(<_>::as_ref)
}
#[inline(always)]
pub fn clear(&mut self) -> &mut Self {
self.0.clear();
self
}
#[inline(always)]
#[must_use]
pub fn is_empty(&self) -> bool {
self.0.is_empty()
}
#[inline(always)]
#[must_use]
pub fn len(&self) -> usize {
self.0.len()
}
#[inline]
pub fn append(&mut self, other: Self) -> &mut Self {
self.0.extend(other.0.into_iter());
self
}
}
impl IntoIterator for ModuleResolversCollection {
type Item = Box<dyn ModuleResolver>;
type IntoIter = IntoIter<Box<dyn ModuleResolver>>;
#[inline(always)]
fn into_iter(self) -> Self::IntoIter {
self.0.into_iter()
}
}
impl<'a> IntoIterator for &'a ModuleResolversCollection {
type Item = &'a Box<dyn ModuleResolver>;
type IntoIter = Iter<'a, Box<dyn ModuleResolver>>;
#[inline(always)]
fn into_iter(self) -> Self::IntoIter {
self.0.iter()
}
}
impl ModuleResolver for ModuleResolversCollection {
fn resolve(
&self,
engine: &Engine,
source_path: Option<&str>,
path: &str,
pos: Position,
) -> RhaiResultOf<Shared<Module>> {
for resolver in &self.0 {
match resolver.resolve(engine, source_path, path, pos) {
Ok(module) => return Ok(module),
Err(err) => match *err {
ERR::ErrorModuleNotFound(..) => continue,
ERR::ErrorInModule(_, err, _) => return Err(err),
_ => panic!("ModuleResolver::resolve returns error that is not ErrorModuleNotFound or ErrorInModule"),
},
}
}
Err(ERR::ErrorModuleNotFound(path.into(), pos).into())
}
}
impl<M: ModuleResolver + 'static> AddAssign<M> for ModuleResolversCollection {
#[inline(always)]
fn add_assign(&mut self, rhs: M) {
self.push(rhs);
}
}