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
|
// Insert the new plugin as enabled, and removes its previous ordering if it was
|
||||||
// already present
|
// already present
|
||||||
fn upsert_plugin_state<T: Plugin>(&mut self, plugin: T, added_at_index: usize) {
|
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>(),
|
TypeId::of::<T>(),
|
||||||
PluginEntry {
|
PluginEntry {
|
||||||
plugin: Box::new(plugin),
|
plugin: Box::new(plugin),
|
||||||
enabled: true,
|
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 {
|
if entry.enabled {
|
||||||
warn!(
|
warn!(
|
||||||
"You are replacing plugin '{}' that was not disabled.",
|
"You are replacing plugin '{}' that was not disabled.",
|
||||||
@ -83,7 +95,7 @@ impl PluginGroupBuilder {
|
|||||||
.order
|
.order
|
||||||
.iter()
|
.iter()
|
||||||
.enumerate()
|
.enumerate()
|
||||||
.find(|(i, ty)| *i != added_at_index && **ty == TypeId::of::<T>())
|
.find(|(i, ty)| *i != added_at_index && **ty == key)
|
||||||
.map(|(i, _)| i)
|
.map(|(i, _)| i)
|
||||||
{
|
{
|
||||||
self.order.remove(to_remove);
|
self.order.remove(to_remove);
|
||||||
@ -118,6 +130,26 @@ impl PluginGroupBuilder {
|
|||||||
self
|
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`.
|
/// 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
|
/// 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.
|
/// 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