rhai/module/resolvers/
collection.rs1use crate::eval::GlobalRuntimeState;
2use crate::{
3 Engine, ModuleResolver, Position, RhaiResultOf, Scope, SharedModule, StaticVec, AST, ERR,
4 STATIC_VEC_INLINE_SIZE,
5};
6#[cfg(feature = "no_std")]
7use std::prelude::v1::*;
8use std::{ops::AddAssign, slice::Iter};
9
10#[derive(Default)]
28pub struct ModuleResolversCollection(StaticVec<Box<dyn ModuleResolver>>);
29
30impl ModuleResolversCollection {
31 #[inline(always)]
48 #[must_use]
49 pub const fn new() -> Self {
50 Self(StaticVec::new_const())
51 }
52 #[inline(always)]
54 pub fn push(&mut self, resolver: impl ModuleResolver + 'static) -> &mut Self {
55 self.0.push(Box::new(resolver));
56 self
57 }
58 #[inline(always)]
64 pub fn insert(&mut self, index: usize, resolver: impl ModuleResolver + 'static) -> &mut Self {
65 self.0.insert(index, Box::new(resolver));
66 self
67 }
68 #[inline(always)]
70 pub fn pop(&mut self) -> Option<Box<dyn ModuleResolver>> {
71 self.0.pop()
72 }
73 #[inline(always)]
79 pub fn remove(&mut self, index: usize) -> Box<dyn ModuleResolver> {
80 self.0.remove(index)
81 }
82 #[inline]
84 pub fn iter(&self) -> impl Iterator<Item = &dyn ModuleResolver> {
85 self.0.iter().map(<_>::as_ref)
86 }
87 #[inline(always)]
89 pub fn clear(&mut self) -> &mut Self {
90 self.0.clear();
91 self
92 }
93 #[inline(always)]
95 #[must_use]
96 pub fn is_empty(&self) -> bool {
97 self.0.is_empty()
98 }
99 #[inline(always)]
101 #[must_use]
102 pub fn len(&self) -> usize {
103 self.0.len()
104 }
105 #[inline]
108 pub fn append(&mut self, other: Self) -> &mut Self {
109 self.0.extend(other.0);
110 self
111 }
112}
113
114impl IntoIterator for ModuleResolversCollection {
115 type Item = Box<dyn ModuleResolver>;
116 type IntoIter = smallvec::IntoIter<[Box<dyn ModuleResolver>; STATIC_VEC_INLINE_SIZE]>;
117
118 #[inline(always)]
119 fn into_iter(self) -> Self::IntoIter {
120 self.0.into_iter()
121 }
122}
123
124impl<'a> IntoIterator for &'a ModuleResolversCollection {
125 type Item = &'a Box<dyn ModuleResolver>;
126 type IntoIter = Iter<'a, Box<dyn ModuleResolver>>;
127
128 #[inline(always)]
129 fn into_iter(self) -> Self::IntoIter {
130 self.0.iter()
131 }
132}
133
134impl Extend<Box<dyn ModuleResolver>> for ModuleResolversCollection {
135 #[inline(always)]
136 fn extend<T: IntoIterator<Item = Box<dyn ModuleResolver>>>(&mut self, iter: T) {
137 self.0.extend(iter);
138 }
139}
140
141impl<M: ModuleResolver + 'static> AddAssign<M> for ModuleResolversCollection {
142 #[inline(always)]
143 fn add_assign(&mut self, rhs: M) {
144 self.push(rhs);
145 }
146}
147
148impl ModuleResolver for ModuleResolversCollection {
149 fn resolve(
150 &self,
151 engine: &Engine,
152 source_path: Option<&str>,
153 path: &str,
154 pos: Position,
155 ) -> RhaiResultOf<SharedModule> {
156 for resolver in &self.0 {
157 match resolver.resolve(engine, source_path, path, pos) {
158 Ok(module) => return Ok(module),
159 Err(err) => match *err {
160 ERR::ErrorModuleNotFound(..) => (),
161 ERR::ErrorInModule(..) => return Err(err),
162 _ => unreachable!("ModuleResolver::resolve returns error that is not ErrorModuleNotFound or ErrorInModule"),
163 },
164 }
165 }
166
167 Err(ERR::ErrorModuleNotFound(path.into(), pos).into())
168 }
169
170 fn resolve_raw(
171 &self,
172 engine: &Engine,
173 global: &mut GlobalRuntimeState,
174 scope: &mut Scope,
175 path: &str,
176 pos: Position,
177 ) -> RhaiResultOf<SharedModule> {
178 for resolver in &self.0 {
179 match resolver.resolve_raw(engine,global, scope, path, pos) {
180 Ok(module) => return Ok(module),
181 Err(err) => match *err {
182 ERR::ErrorModuleNotFound(..) => (),
183 ERR::ErrorInModule(..) => return Err(err),
184 _ => unreachable!("ModuleResolver::resolve returns error that is not ErrorModuleNotFound or ErrorInModule"),
185 },
186 }
187 }
188
189 Err(ERR::ErrorModuleNotFound(path.into(), pos).into())
190 }
191
192 fn resolve_ast(
193 &self,
194 engine: &Engine,
195 source: Option<&str>,
196 path: &str,
197 pos: Position,
198 ) -> Option<RhaiResultOf<AST>> {
199 for resolver in &self.0 {
200 match resolver.resolve_ast(engine, source, path, pos) {
201 None => (),
202 Some(Err(err)) => match *err {
203 ERR::ErrorModuleNotFound(..) => (),
204 _ => unreachable!("ModuleResolver::resolve_ast returns error that is not ErrorModuleNotFound or ErrorInModule"),
205 },
206 r => return r,
207 }
208 }
209
210 None
211 }
212}