Add Module::fill_with.

This commit is contained in:
Stephen Chung 2020-10-25 00:39:47 +08:00
parent 2c7c719cd5
commit 65432330c4
2 changed files with 69 additions and 60 deletions

View File

@ -2,6 +2,15 @@ Rhai Release Notes
==================
Version 0.19.4
==============
New features
------------
* `Module::fill_with` to poly-fill a module with another.
Version 0.19.3
==============

View File

@ -1125,18 +1125,10 @@ impl Module {
/// The other module is consumed to merge into this module.
#[inline]
pub fn combine(&mut self, other: Self) -> &mut Self {
if !other.modules.is_empty() {
self.modules.extend(other.modules.into_iter());
}
if !other.variables.is_empty() {
self.variables.extend(other.variables.into_iter());
}
if !other.functions.is_empty() {
self.functions.extend(other.functions.into_iter());
}
if !other.type_iterators.is_empty() {
self.type_iterators.extend(other.type_iterators.into_iter());
}
self.modules.extend(other.modules.into_iter());
self.variables.extend(other.variables.into_iter());
self.functions.extend(other.functions.into_iter());
self.type_iterators.extend(other.type_iterators.into_iter());
self.all_functions.clear();
self.all_variables.clear();
self.indexed = false;
@ -1148,20 +1140,38 @@ impl Module {
/// Sub-modules are flattened onto the root module, with higher level overriding lower level.
#[inline]
pub fn combine_flatten(&mut self, other: Self) -> &mut Self {
if !other.modules.is_empty() {
other.modules.into_iter().for_each(|(_, m)| {
self.combine_flatten(m);
});
}
if !other.variables.is_empty() {
self.variables.extend(other.variables.into_iter());
}
if !other.functions.is_empty() {
self.functions.extend(other.functions.into_iter());
}
if !other.type_iterators.is_empty() {
self.type_iterators.extend(other.type_iterators.into_iter());
}
other.modules.into_iter().for_each(|(_, m)| {
self.combine_flatten(m);
});
self.variables.extend(other.variables.into_iter());
self.functions.extend(other.functions.into_iter());
self.type_iterators.extend(other.type_iterators.into_iter());
self.all_functions.clear();
self.all_variables.clear();
self.indexed = false;
self
}
/// Poly-fill this module with another module.
/// Only items not existing in this module are added.
#[inline]
pub fn fill_with(&mut self, other: &Self) -> &mut Self {
other.modules.iter().for_each(|(k, v)| {
if !self.modules.contains_key(k) {
self.modules.insert(k.clone(), v.clone());
}
});
other.variables.iter().for_each(|(k, v)| {
if !self.variables.contains_key(k) {
self.variables.insert(k.clone(), v.clone());
}
});
other.functions.iter().for_each(|(&k, v)| {
self.functions.entry(k).or_insert_with(|| v.clone());
});
other.type_iterators.iter().for_each(|(&k, &v)| {
self.type_iterators.entry(k).or_insert(v);
});
self.all_functions.clear();
self.all_variables.clear();
self.indexed = false;
@ -1181,42 +1191,32 @@ impl Module {
mut _filter: &mut impl FnMut(FnAccess, &str, usize) -> bool,
) -> &mut Self {
#[cfg(not(feature = "no_function"))]
if !other.modules.is_empty() {
other.modules.iter().for_each(|(k, v)| {
let mut m = Self::new();
m.merge_filtered(v, _filter);
self.modules.insert(k.clone(), m);
});
}
other.modules.iter().for_each(|(k, v)| {
let mut m = Self::new();
m.merge_filtered(v, _filter);
self.modules.insert(k.clone(), m);
});
#[cfg(feature = "no_function")]
if !other.modules.is_empty() {
self.modules
.extend(other.modules.iter().map(|(k, v)| (k.clone(), v.clone())));
}
if !other.variables.is_empty() {
self.variables
.extend(other.variables.iter().map(|(k, v)| (k.clone(), v.clone())));
}
if !other.functions.is_empty() {
self.functions.extend(
other
.functions
.iter()
.filter(|(_, (_, _, _, _, v))| match v {
#[cfg(not(feature = "no_function"))]
CallableFunction::Script(f) => {
_filter(f.access, f.name.as_str(), f.params.len())
}
_ => true,
})
.map(|(&k, v)| (k, v.clone())),
);
}
self.modules
.extend(other.modules.iter().map(|(k, v)| (k.clone(), v.clone())));
if !other.type_iterators.is_empty() {
self.type_iterators
.extend(other.type_iterators.iter().map(|(&k, v)| (k, v.clone())));
}
self.variables
.extend(other.variables.iter().map(|(k, v)| (k.clone(), v.clone())));
self.functions.extend(
other
.functions
.iter()
.filter(|(_, (_, _, _, _, v))| match v {
#[cfg(not(feature = "no_function"))]
CallableFunction::Script(f) => {
_filter(f.access, f.name.as_str(), f.params.len())
}
_ => true,
})
.map(|(&k, v)| (k, v.clone())),
);
self.type_iterators.extend(other.type_iterators.iter());
self.all_functions.clear();
self.all_variables.clear();
self.indexed = false;