diff --git a/src/module/mod.rs b/src/module/mod.rs index 6d9681e6..305cdbc9 100644 --- a/src/module/mod.rs +++ b/src/module/mod.rs @@ -33,7 +33,7 @@ use crate::stdlib::{ fmt, format, iter::empty, num::NonZeroUsize, - ops::{Deref, DerefMut}, + ops::{Add, AddAssign, Deref, DerefMut}, string::{String, ToString}, vec::Vec, }; @@ -1546,6 +1546,38 @@ impl From> for ModuleRef { } } +impl Add for Module { + type Output = Self; + + fn add(self, rhs: Module) -> Self::Output { + let mut module = self.clone(); + module.merge(&rhs); + module + } +} + +impl Add<&Module> for Module { + type Output = Self; + + fn add(self, rhs: &Module) -> Self::Output { + let mut module = self.clone(); + module.merge(rhs); + module + } +} + +impl AddAssign for Module { + fn add_assign(&mut self, rhs: Module) { + self.combine(rhs); + } +} + +impl AddAssign<&Module> for Module { + fn add_assign(&mut self, rhs: &Module) { + self.merge(rhs); + } +} + impl ModuleRef { pub(crate) fn index(&self) -> Option { self.1 diff --git a/src/module/resolvers/collection.rs b/src/module/resolvers/collection.rs index e513f51e..3c9eefa3 100644 --- a/src/module/resolvers/collection.rs +++ b/src/module/resolvers/collection.rs @@ -3,7 +3,7 @@ use crate::module::{Module, ModuleResolver}; use crate::result::EvalAltResult; use crate::token::Position; -use crate::stdlib::{boxed::Box, vec::Vec}; +use crate::stdlib::{boxed::Box, ops::AddAssign, vec::Vec}; /// Module resolution service that holds a collection of module resolves, /// to be searched in sequential order. @@ -45,9 +45,6 @@ impl ModuleResolversCollection { pub fn new() -> Self { Default::default() } -} - -impl ModuleResolversCollection { /// Add a module keyed by its path. pub fn push(&mut self, resolver: impl ModuleResolver + 'static) { self.0.push(Box::new(resolver)); @@ -56,10 +53,29 @@ impl ModuleResolversCollection { pub fn iter(&self) -> impl Iterator { self.0.iter().map(|v| v.as_ref()) } + /// Get a mutable iterator of all the modules. + pub fn into_iter(self) -> impl Iterator> { + self.0.into_iter() + } /// Remove all module resolvers. pub fn clear(&mut self) { self.0.clear(); } + /// Is this `ModuleResolversCollection` empty? + pub fn is_empty(&self) -> bool { + self.0.is_empty() + } + /// Get the number of module resolvers in this `ModuleResolversCollection`. + pub fn len(&self) -> usize { + self.0.len() + } + /// Add another `ModuleResolversCollection` to the end of this collection. + /// The other `ModuleResolversCollection` is consumed. + pub fn append(&mut self, other: Self) { + if !other.is_empty() { + self.0.extend(other.0.into_iter()); + } + } } impl ModuleResolver for ModuleResolversCollection { @@ -83,3 +99,9 @@ impl ModuleResolver for ModuleResolversCollection { EvalAltResult::ErrorModuleNotFound(path.into(), pos).into() } } + +impl AddAssign for ModuleResolversCollection { + fn add_assign(&mut self, rhs: M) { + self.push(rhs); + } +} diff --git a/src/module/resolvers/stat.rs b/src/module/resolvers/stat.rs index 563f5074..547bd5af 100644 --- a/src/module/resolvers/stat.rs +++ b/src/module/resolvers/stat.rs @@ -3,7 +3,7 @@ use crate::module::{Module, ModuleResolver}; use crate::result::EvalAltResult; use crate::token::Position; -use crate::stdlib::{boxed::Box, collections::HashMap, string::String}; +use crate::stdlib::{boxed::Box, collections::HashMap, ops::AddAssign, string::String}; /// Module resolution service that serves modules added into it. /// @@ -45,9 +45,6 @@ impl StaticModuleResolver { pub fn new() -> Self { Default::default() } -} - -impl StaticModuleResolver { /// Add a module keyed by its path. pub fn insert>(&mut self, path: S, module: Module) { self.0.insert(path.into(), module); @@ -68,6 +65,10 @@ impl StaticModuleResolver { pub fn iter_mut(&mut self) -> impl Iterator { self.0.iter_mut().map(|(k, v)| (k.as_str(), v)) } + /// Get a mutable iterator of all the modules. + pub fn into_iter(self) -> impl Iterator { + self.0.into_iter() + } /// Get an iterator of all the module paths. pub fn paths(&self) -> impl Iterator { self.0.keys().map(String::as_str) @@ -84,6 +85,21 @@ impl StaticModuleResolver { pub fn clear(&mut self) { self.0.clear(); } + /// Is this `StaticModuleResolver` empty? + pub fn is_empty(&self) -> bool { + self.0.is_empty() + } + /// Get the number of modules in this `StaticModuleResolver`. + pub fn len(&self) -> usize { + self.0.len() + } + /// Merge another `StaticModuleResolver` into this. + /// The other `StaticModuleResolver` is consumed. + pub fn merge(&mut self, other: Self) { + if !other.is_empty() { + self.0.extend(other.0.into_iter()); + } + } } impl ModuleResolver for StaticModuleResolver { @@ -94,3 +110,9 @@ impl ModuleResolver for StaticModuleResolver { .ok_or_else(|| EvalAltResult::ErrorModuleNotFound(path.into(), pos).into()) } } + +impl AddAssign for StaticModuleResolver { + fn add_assign(&mut self, rhs: Self) { + self.merge(rhs); + } +} diff --git a/src/parser.rs b/src/parser.rs index b2b30bb3..c83daba9 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -459,7 +459,7 @@ impl Add<&Self> for &AST { } } -impl AddAssign for &mut AST { +impl AddAssign for AST { fn add_assign(&mut self, rhs: AST) { self.combine(rhs); }