Added add_group
to PluginGroupBuilder
(#9530)
# Objective - Fixes #751 ## Solution - Added `PluginGroupBuilder::add_group`, which accepts an owned `impl PluginGroup` and adds those plugins to self, following `PluginGroupBuilder::add`'s replacement rules. - Split `PluginGroupBuilder::upsert_plugin_state` into two functions, one of the same name, and `PluginGroupBuilder::upsert_plugin_entry_state` which takes a `PluginEntry` and `TypeId` directly. This allows for shared behaviour between `add` and `add_group`. - Added 2 unit tests documenting the replacement behaviour in `PluginGroupBuilder::add_group`. Co-authored-by: François <mockersf@gmail.com>
This commit is contained in:
parent
5bcc100d10
commit
bb00d9fc3c
@ -66,13 +66,25 @@ impl PluginGroupBuilder {
|
||||
// Insert the new plugin as enabled, and removes its previous ordering if it was
|
||||
// already present
|
||||
fn upsert_plugin_state<T: Plugin>(&mut self, plugin: T, added_at_index: usize) {
|
||||
if let Some(entry) = self.plugins.insert(
|
||||
self.upsert_plugin_entry_state(
|
||||
TypeId::of::<T>(),
|
||||
PluginEntry {
|
||||
plugin: Box::new(plugin),
|
||||
enabled: true,
|
||||
},
|
||||
) {
|
||||
added_at_index,
|
||||
);
|
||||
}
|
||||
|
||||
// Insert the new plugin entry as enabled, and removes its previous ordering if it was
|
||||
// already present
|
||||
fn upsert_plugin_entry_state(
|
||||
&mut self,
|
||||
key: TypeId,
|
||||
plugin: PluginEntry,
|
||||
added_at_index: usize,
|
||||
) {
|
||||
if let Some(entry) = self.plugins.insert(key, plugin) {
|
||||
if entry.enabled {
|
||||
warn!(
|
||||
"You are replacing plugin '{}' that was not disabled.",
|
||||
@ -83,7 +95,7 @@ impl PluginGroupBuilder {
|
||||
.order
|
||||
.iter()
|
||||
.enumerate()
|
||||
.find(|(i, ty)| *i != added_at_index && **ty == TypeId::of::<T>())
|
||||
.find(|(i, ty)| *i != added_at_index && **ty == key)
|
||||
.map(|(i, _)| i)
|
||||
{
|
||||
self.order.remove(to_remove);
|
||||
@ -118,6 +130,26 @@ impl PluginGroupBuilder {
|
||||
self
|
||||
}
|
||||
|
||||
/// Adds a [`PluginGroup`] at the end of this [`PluginGroupBuilder`]. If the plugin was
|
||||
/// already in the group, it is removed from its previous place.
|
||||
pub fn add_group(mut self, group: impl PluginGroup) -> Self {
|
||||
let Self {
|
||||
mut plugins, order, ..
|
||||
} = group.build();
|
||||
|
||||
for plugin_id in order {
|
||||
self.upsert_plugin_entry_state(
|
||||
plugin_id,
|
||||
plugins.remove(&plugin_id).unwrap(),
|
||||
self.order.len(),
|
||||
);
|
||||
|
||||
self.order.push(plugin_id);
|
||||
}
|
||||
|
||||
self
|
||||
}
|
||||
|
||||
/// Adds a [`Plugin`] in this [`PluginGroupBuilder`] before the plugin of type `Target`.
|
||||
/// If the plugin was already the group, it is removed from its previous place. There must
|
||||
/// be a plugin of type `Target` in the group or it will panic.
|
||||
@ -335,4 +367,48 @@ mod tests {
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn add_basic_subgroup() {
|
||||
let group_a = PluginGroupBuilder::start::<NoopPluginGroup>()
|
||||
.add(PluginA)
|
||||
.add(PluginB);
|
||||
|
||||
let group_b = PluginGroupBuilder::start::<NoopPluginGroup>()
|
||||
.add_group(group_a)
|
||||
.add(PluginC);
|
||||
|
||||
assert_eq!(
|
||||
group_b.order,
|
||||
vec![
|
||||
std::any::TypeId::of::<PluginA>(),
|
||||
std::any::TypeId::of::<PluginB>(),
|
||||
std::any::TypeId::of::<PluginC>(),
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn add_conflicting_subgroup() {
|
||||
let group_a = PluginGroupBuilder::start::<NoopPluginGroup>()
|
||||
.add(PluginA)
|
||||
.add(PluginC);
|
||||
|
||||
let group_b = PluginGroupBuilder::start::<NoopPluginGroup>()
|
||||
.add(PluginB)
|
||||
.add(PluginC);
|
||||
|
||||
let group = PluginGroupBuilder::start::<NoopPluginGroup>()
|
||||
.add_group(group_a)
|
||||
.add_group(group_b);
|
||||
|
||||
assert_eq!(
|
||||
group.order,
|
||||
vec![
|
||||
std::any::TypeId::of::<PluginA>(),
|
||||
std::any::TypeId::of::<PluginB>(),
|
||||
std::any::TypeId::of::<PluginC>(),
|
||||
]
|
||||
);
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user