Code enhancements.
This commit is contained in:
@@ -35,9 +35,9 @@ use crate::Map;
|
||||
/// A type representing the namespace of a function.
|
||||
#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)]
|
||||
pub enum FnNamespace {
|
||||
/// Global namespace.
|
||||
/// Expose to global namespace.
|
||||
Global,
|
||||
/// Internal only.
|
||||
/// Module namespace only.
|
||||
Internal,
|
||||
}
|
||||
|
||||
@@ -465,6 +465,16 @@ impl Module {
|
||||
.map(|FuncInfo { func, .. }| func.get_fn_def())
|
||||
}
|
||||
|
||||
/// Get a mutable reference to the underlying [`HashMap`] of sub-modules.
|
||||
#[inline(always)]
|
||||
pub(crate) fn sub_modules_mut(&mut self) -> &mut HashMap<ImmutableString, Shared<Module>> {
|
||||
// We must assume that the user has changed the sub-modules
|
||||
// (otherwise why take a mutable reference?)
|
||||
self.indexed = false;
|
||||
|
||||
&mut self.modules
|
||||
}
|
||||
|
||||
/// Does a sub-module exist in the module?
|
||||
///
|
||||
/// # Example
|
||||
@@ -1699,7 +1709,7 @@ impl Module {
|
||||
ast: &crate::AST,
|
||||
engine: &crate::Engine,
|
||||
) -> Result<Self, Box<EvalAltResult>> {
|
||||
let mut mods = engine.global_sub_modules.clone();
|
||||
let mut mods: crate::engine::Imports = (&engine.global_sub_modules).into();
|
||||
let orig_mods_len = mods.len();
|
||||
|
||||
// Run the script
|
||||
|
@@ -16,7 +16,7 @@ use crate::{Engine, EvalAltResult, Module, ModuleResolver, Position, Shared};
|
||||
/// collection.push(resolver);
|
||||
///
|
||||
/// let mut engine = Engine::new();
|
||||
/// engine.set_module_resolver(Some(collection));
|
||||
/// engine.set_module_resolver(collection);
|
||||
/// ```
|
||||
#[derive(Default)]
|
||||
pub struct ModuleResolversCollection(Vec<Box<dyn ModuleResolver>>);
|
||||
@@ -36,16 +36,41 @@ impl ModuleResolversCollection {
|
||||
/// collection.push(resolver);
|
||||
///
|
||||
/// let mut engine = Engine::new();
|
||||
/// engine.set_module_resolver(Some(collection));
|
||||
/// engine.set_module_resolver(collection);
|
||||
/// ```
|
||||
#[inline(always)]
|
||||
pub fn new() -> Self {
|
||||
Default::default()
|
||||
}
|
||||
/// Add a module keyed by its path.
|
||||
/// Append a module resolver to the end.
|
||||
#[inline(always)]
|
||||
pub fn push(&mut self, resolver: impl ModuleResolver + 'static) {
|
||||
pub fn push(&mut self, resolver: impl ModuleResolver + 'static) -> &mut Self {
|
||||
self.0.push(Box::new(resolver));
|
||||
self
|
||||
}
|
||||
/// Insert a module resolver to an offset index.
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// Panics if the index is out of bounds.
|
||||
#[inline(always)]
|
||||
pub fn insert(&mut self, index: usize, resolver: impl ModuleResolver + 'static) -> &mut Self {
|
||||
self.0.insert(index, Box::new(resolver));
|
||||
self
|
||||
}
|
||||
/// Remove the last module resolver from the end, if any.
|
||||
#[inline(always)]
|
||||
pub fn pop(&mut self) -> Option<Box<dyn ModuleResolver>> {
|
||||
self.0.pop()
|
||||
}
|
||||
/// Remove a module resolver at an offset index.
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// Panics if the index is out of bounds.
|
||||
#[inline(always)]
|
||||
pub fn remove(&mut self, index: usize) -> Box<dyn ModuleResolver> {
|
||||
self.0.remove(index)
|
||||
}
|
||||
/// Get an iterator of all the module resolvers.
|
||||
#[inline(always)]
|
||||
@@ -59,8 +84,9 @@ impl ModuleResolversCollection {
|
||||
}
|
||||
/// Remove all module resolvers.
|
||||
#[inline(always)]
|
||||
pub fn clear(&mut self) {
|
||||
pub fn clear(&mut self) -> &mut Self {
|
||||
self.0.clear();
|
||||
self
|
||||
}
|
||||
/// Is this [`ModuleResolversCollection`] empty?
|
||||
#[inline(always)]
|
||||
@@ -75,8 +101,9 @@ impl ModuleResolversCollection {
|
||||
/// Add another [`ModuleResolversCollection`] to the end of this collection.
|
||||
/// The other [`ModuleResolversCollection`] is consumed.
|
||||
#[inline(always)]
|
||||
pub fn append(&mut self, other: Self) {
|
||||
pub fn append(&mut self, other: Self) -> &mut Self {
|
||||
self.0.extend(other.0.into_iter());
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
|
48
src/module/resolvers/dummy.rs
Normal file
48
src/module/resolvers/dummy.rs
Normal file
@@ -0,0 +1,48 @@
|
||||
use crate::stdlib::boxed::Box;
|
||||
use crate::{Engine, EvalAltResult, Module, ModuleResolver, Position, Shared};
|
||||
|
||||
/// Empty/disabled module resolution service that acts as a dummy.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```
|
||||
/// use rhai::{Engine, Module};
|
||||
/// use rhai::module_resolvers::DummyModuleResolver;
|
||||
///
|
||||
/// let resolver = DummyModuleResolver::new();
|
||||
/// let mut engine = Engine::new();
|
||||
/// engine.set_module_resolver(resolver);
|
||||
/// ```
|
||||
#[derive(Debug, Copy, Eq, PartialEq, Clone, Default, Hash)]
|
||||
pub struct DummyModuleResolver;
|
||||
|
||||
impl DummyModuleResolver {
|
||||
/// Create a new [`DummyModuleResolver`].
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```
|
||||
/// use rhai::{Engine, Module};
|
||||
/// use rhai::module_resolvers::DummyModuleResolver;
|
||||
///
|
||||
/// let resolver = DummyModuleResolver::new();
|
||||
/// let mut engine = Engine::new();
|
||||
/// engine.set_module_resolver(resolver);
|
||||
/// ```
|
||||
#[inline(always)]
|
||||
pub fn new() -> Self {
|
||||
Default::default()
|
||||
}
|
||||
}
|
||||
|
||||
impl ModuleResolver for DummyModuleResolver {
|
||||
#[inline(always)]
|
||||
fn resolve(
|
||||
&self,
|
||||
_: &Engine,
|
||||
path: &str,
|
||||
pos: Position,
|
||||
) -> Result<Shared<Module>, Box<EvalAltResult>> {
|
||||
EvalAltResult::ErrorModuleNotFound(path.into(), pos).into()
|
||||
}
|
||||
}
|
@@ -1,5 +1,9 @@
|
||||
use crate::stdlib::{
|
||||
boxed::Box, collections::HashMap, io::Error as IoError, path::PathBuf, string::String,
|
||||
boxed::Box,
|
||||
collections::HashMap,
|
||||
io::Error as IoError,
|
||||
path::{Path, PathBuf},
|
||||
string::String,
|
||||
};
|
||||
use crate::{Engine, EvalAltResult, Module, ModuleResolver, Position, Shared};
|
||||
|
||||
@@ -31,7 +35,7 @@ use crate::{Engine, EvalAltResult, Module, ModuleResolver, Position, Shared};
|
||||
///
|
||||
/// let mut engine = Engine::new();
|
||||
///
|
||||
/// engine.set_module_resolver(Some(resolver));
|
||||
/// engine.set_module_resolver(resolver);
|
||||
/// ```
|
||||
#[derive(Debug)]
|
||||
pub struct FileModuleResolver {
|
||||
@@ -65,10 +69,10 @@ impl FileModuleResolver {
|
||||
/// let resolver = FileModuleResolver::new_with_path("./scripts");
|
||||
///
|
||||
/// let mut engine = Engine::new();
|
||||
/// engine.set_module_resolver(Some(resolver));
|
||||
/// engine.set_module_resolver(resolver);
|
||||
/// ```
|
||||
#[inline(always)]
|
||||
pub fn new_with_path<P: Into<PathBuf>>(path: P) -> Self {
|
||||
pub fn new_with_path(path: impl Into<PathBuf>) -> Self {
|
||||
Self::new_with_path_and_extension(path, "rhai")
|
||||
}
|
||||
|
||||
@@ -87,12 +91,12 @@ impl FileModuleResolver {
|
||||
/// let resolver = FileModuleResolver::new_with_path_and_extension("./scripts", "x");
|
||||
///
|
||||
/// let mut engine = Engine::new();
|
||||
/// engine.set_module_resolver(Some(resolver));
|
||||
/// engine.set_module_resolver(resolver);
|
||||
/// ```
|
||||
#[inline(always)]
|
||||
pub fn new_with_path_and_extension<P: Into<PathBuf>, E: Into<String>>(
|
||||
path: P,
|
||||
extension: E,
|
||||
pub fn new_with_path_and_extension(
|
||||
path: impl Into<PathBuf>,
|
||||
extension: impl Into<String>,
|
||||
) -> Self {
|
||||
Self {
|
||||
path: path.into(),
|
||||
@@ -114,12 +118,64 @@ impl FileModuleResolver {
|
||||
/// let resolver = FileModuleResolver::new();
|
||||
///
|
||||
/// let mut engine = Engine::new();
|
||||
/// engine.set_module_resolver(Some(resolver));
|
||||
/// engine.set_module_resolver(resolver);
|
||||
/// ```
|
||||
#[inline(always)]
|
||||
pub fn new() -> Self {
|
||||
Default::default()
|
||||
}
|
||||
|
||||
/// Get the base path for script files.
|
||||
#[inline(always)]
|
||||
pub fn path(&self) -> &Path {
|
||||
self.path.as_ref()
|
||||
}
|
||||
/// Set the base path for script files.
|
||||
#[inline(always)]
|
||||
pub fn set_path(&mut self, path: impl Into<PathBuf>) -> &mut Self {
|
||||
self.path = path.into();
|
||||
self
|
||||
}
|
||||
|
||||
/// Get the script file extension.
|
||||
#[inline(always)]
|
||||
pub fn extension(&self) -> &str {
|
||||
&self.extension
|
||||
}
|
||||
|
||||
/// Set the script file extension.
|
||||
#[inline(always)]
|
||||
pub fn set_extension(&mut self, extension: impl Into<String>) -> &mut Self {
|
||||
self.extension = extension.into();
|
||||
self
|
||||
}
|
||||
|
||||
/// Empty the internal cache.
|
||||
#[inline(always)]
|
||||
pub fn clear_cache(&mut self) {
|
||||
#[cfg(not(feature = "sync"))]
|
||||
self.cache.borrow_mut().clear();
|
||||
#[cfg(feature = "sync")]
|
||||
self.cache.write().unwrap().clear();
|
||||
}
|
||||
|
||||
/// Empty the internal cache.
|
||||
#[inline(always)]
|
||||
pub fn clear_cache_for_path(&mut self, path: impl AsRef<Path>) -> Option<Shared<Module>> {
|
||||
#[cfg(not(feature = "sync"))]
|
||||
return self
|
||||
.cache
|
||||
.borrow_mut()
|
||||
.remove_entry(path.as_ref())
|
||||
.map(|(_, v)| v);
|
||||
#[cfg(feature = "sync")]
|
||||
return self
|
||||
.cache
|
||||
.write()
|
||||
.unwrap()
|
||||
.remove_entry(path.as_ref())
|
||||
.map(|(_, v)| v);
|
||||
}
|
||||
}
|
||||
|
||||
impl ModuleResolver for FileModuleResolver {
|
||||
|
@@ -2,6 +2,9 @@ use crate::fn_native::SendSync;
|
||||
use crate::stdlib::boxed::Box;
|
||||
use crate::{Engine, EvalAltResult, Module, Position, Shared};
|
||||
|
||||
mod dummy;
|
||||
pub use dummy::DummyModuleResolver;
|
||||
|
||||
mod collection;
|
||||
pub use collection::ModuleResolversCollection;
|
||||
|
||||
|
@@ -16,7 +16,7 @@ use crate::{Engine, EvalAltResult, Module, ModuleResolver, Position, Shared};
|
||||
///
|
||||
/// let mut engine = Engine::new();
|
||||
///
|
||||
/// engine.set_module_resolver(Some(resolver));
|
||||
/// engine.set_module_resolver(resolver);
|
||||
/// ```
|
||||
#[derive(Debug, Clone, Default)]
|
||||
pub struct StaticModuleResolver(HashMap<String, Shared<Module>>);
|
||||
@@ -36,7 +36,7 @@ impl StaticModuleResolver {
|
||||
/// resolver.insert("hello", module);
|
||||
///
|
||||
/// let mut engine = Engine::new();
|
||||
/// engine.set_module_resolver(Some(resolver));
|
||||
/// engine.set_module_resolver(resolver);
|
||||
/// ```
|
||||
#[inline(always)]
|
||||
pub fn new() -> Self {
|
||||
@@ -60,8 +60,13 @@ impl StaticModuleResolver {
|
||||
}
|
||||
/// Get an iterator of all the modules.
|
||||
#[inline(always)]
|
||||
pub fn iter(&self) -> impl Iterator<Item = (&str, Shared<Module>)> {
|
||||
self.0.iter().map(|(k, v)| (k.as_str(), v.clone()))
|
||||
pub fn iter(&self) -> impl Iterator<Item = (&str, &Shared<Module>)> {
|
||||
self.0.iter().map(|(k, v)| (k.as_str(), v))
|
||||
}
|
||||
/// Get a mutable iterator of all the modules.
|
||||
#[inline(always)]
|
||||
pub fn iter_mut(&mut self) -> impl Iterator<Item = (&str, &mut Shared<Module>)> {
|
||||
self.0.iter_mut().map(|(k, v)| (k.as_str(), v))
|
||||
}
|
||||
/// Get a mutable iterator of all the modules.
|
||||
#[inline(always)]
|
||||
@@ -75,8 +80,8 @@ impl StaticModuleResolver {
|
||||
}
|
||||
/// Get an iterator of all the modules.
|
||||
#[inline(always)]
|
||||
pub fn values<'a>(&'a self) -> impl Iterator<Item = Shared<Module>> + 'a {
|
||||
self.0.values().map(|m| m.clone())
|
||||
pub fn values(&self) -> impl Iterator<Item = &Shared<Module>> {
|
||||
self.0.values().map(|m| m)
|
||||
}
|
||||
/// Remove all modules.
|
||||
#[inline(always)]
|
||||
@@ -95,6 +100,8 @@ impl StaticModuleResolver {
|
||||
}
|
||||
/// Merge another [`StaticModuleResolver`] into this.
|
||||
/// The other [`StaticModuleResolver`] is consumed.
|
||||
///
|
||||
/// Existing modules of the same path name are overwritten.
|
||||
#[inline(always)]
|
||||
pub fn merge(&mut self, other: Self) {
|
||||
if !other.is_empty() {
|
||||
|
Reference in New Issue
Block a user