1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
use crate::engine::Engine;
use crate::module::{Module, ModuleResolver};
use crate::result::EvalAltResult;
use crate::token::Position;

use crate::stdlib::{boxed::Box, collections::HashMap, ops::AddAssign, string::String};

/// Module resolution service that serves modules added into it.

///

/// # Examples

///

/// ```

/// use rhai::{Engine, Module};

/// use rhai::module_resolvers::StaticModuleResolver;

///

/// let mut resolver = StaticModuleResolver::new();

///

/// let module = Module::new();

/// resolver.insert("hello".to_string(), module);

///

/// let mut engine = Engine::new();

///

/// engine.set_module_resolver(Some(resolver));

/// ```

#[derive(Debug, Clone, Default)]
pub struct StaticModuleResolver(HashMap<String, Module>);

impl StaticModuleResolver {
    /// Create a new `StaticModuleResolver`.

    ///

    /// # Examples

    ///

    /// ```

    /// use rhai::{Engine, Module};

    /// use rhai::module_resolvers::StaticModuleResolver;

    ///

    /// let mut resolver = StaticModuleResolver::new();

    ///

    /// let module = Module::new();

    /// resolver.insert("hello", module);

    ///

    /// let mut engine = Engine::new();

    /// engine.set_module_resolver(Some(resolver));

    /// ```

    #[inline(always)]
    pub fn new() -> Self {
        Default::default()
    }
    /// Add a module keyed by its path.

    #[inline(always)]
    pub fn insert<S: Into<String>>(&mut self, path: S, module: Module) {
        self.0.insert(path.into(), module);
    }
    /// Remove a module given its path.

    #[inline(always)]
    pub fn remove(&mut self, path: &str) -> Option<Module> {
        self.0.remove(path)
    }
    /// Does the path exist?

    #[inline(always)]
    pub fn contains_path(&self, path: &str) -> bool {
        self.0.contains_key(path)
    }
    /// Get an iterator of all the modules.

    #[inline(always)]
    pub fn iter(&self) -> impl Iterator<Item = (&str, &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 Module)> {
        self.0.iter_mut().map(|(k, v)| (k.as_str(), v))
    }
    /// Get a mutable iterator of all the modules.

    #[inline(always)]
    pub fn into_iter(self) -> impl Iterator<Item = (String, Module)> {
        self.0.into_iter()
    }
    /// Get an iterator of all the module paths.

    #[inline(always)]
    pub fn paths(&self) -> impl Iterator<Item = &str> {
        self.0.keys().map(String::as_str)
    }
    /// Get an iterator of all the modules.

    #[inline(always)]
    pub fn values(&self) -> impl Iterator<Item = &Module> {
        self.0.values()
    }
    /// Get a mutable iterator of all the modules.

    #[inline(always)]
    pub fn values_mut(&mut self) -> impl Iterator<Item = &mut Module> {
        self.0.values_mut()
    }
    /// Remove all modules.

    #[inline(always)]
    pub fn clear(&mut self) {
        self.0.clear();
    }
    /// Is this `StaticModuleResolver` empty?

    #[inline(always)]
    pub fn is_empty(&self) -> bool {
        self.0.is_empty()
    }
    /// Get the number of modules in this `StaticModuleResolver`.

    #[inline(always)]
    pub fn len(&self) -> usize {
        self.0.len()
    }
    /// Merge another `StaticModuleResolver` into this.

    /// The other `StaticModuleResolver` is consumed.

    #[inline(always)]
    pub fn merge(&mut self, other: Self) {
        if !other.is_empty() {
            self.0.extend(other.0.into_iter());
        }
    }
}

impl ModuleResolver for StaticModuleResolver {
    #[inline(always)]
    fn resolve(&self, _: &Engine, path: &str, pos: Position) -> Result<Module, Box<EvalAltResult>> {
        self.0
            .get(path)
            .cloned()
            .ok_or_else(|| EvalAltResult::ErrorModuleNotFound(path.into(), pos).into())
    }
}

impl AddAssign<Self> for StaticModuleResolver {
    #[inline(always)]
    fn add_assign(&mut self, rhs: Self) {
        self.merge(rhs);
    }
}