We now have an overview of traits, how to define them and how they work, now it's time to put that knowledge to use and build a plugin system using traits.
A plugin in this system is any type that implements a specific trait. Each plugin will perform a specific task, and the system should manage a collection of these plugins, executing them in sequence. You’ll also address advanced issues like object safety and resolving potential conflicts between overlapping trait implementations.
Design and implement a plugin system using trait objects. You will:
Plugin
trait that includes methods for initialization and execution.PluginManager
struct to manage plugins. It should:
Plugin
trait.Plugin
trait should include the following methods:
fn name(&self) -> &str;
- Returns the name of the plugin.fn execute(&self);
- Executes the plugin's functionality.PluginManager
should:
new() -> Self
- Creates a new PluginManager
instance.add_plugin
- Adds a plugin to the list.remove_plugin
- Removes a plugin from the list.execute_all
- Executes all registered plugins.Make sure you make all relevant items public.
Vec<Box<dyn Plugin>>
for dynamic dispatch.name
method to identify and ensure uniqueness among plugins.pub trait Plugin { // 1. Finish the trait fn name(&self) -> &str; fn execute(&self);}pub struct PluginManager { // 2. Finish the struct // Make fields public pub plugins: Vec<Box<dyn Plugin>>,}// 3. Implement the PluginManagerimpl PluginManager { pub fn new() -> Self { Self { plugins: vec![] } } pub fn add_plugin(&mut self, p: Box<dyn Plugin>) { let mut flag = false; for _p in self.plugins.iter() { if _p.name() == p.name() { flag = true } } if flag { panic!("Plugin with name '{}' already exists", p.name()); } self.plugins.push(p); } pub fn remove_plugin(&mut self, name: &str) -> Option<Box<dyn Plugin>> { let mut target = 0; let mut flag = false; for (i, p) in self.plugins.iter().enumerate() { if p.name() == name { target = i; flag = true; break; } } if flag { return Some(self.plugins.remove(target)); } else { None } } pub fn execute_all(&self) { for p in self.plugins.iter() { p.execute(); } }}// Example usage// pub fn main() {// let mut manager = PluginManager::new();// manager.add_plugin(Box::new(MyPlugin::new()));// manager.execute_all();// }
pub trait Plugin { fn name(&self) -> &str; fn execute(&self);}pub struct PluginManager { // 2. Finish the struct // Make fields public pub plugins: Vec<Box<dyn Plugin>>,}// 3. Implement the PluginManagerimpl PluginManager { pub fn new() -> PluginManager { Self { plugins: Vec::new(), } } pub fn add_plugin(&mut self, plugin: Box<dyn Plugin>) { self.plugins.iter().find(|&p| p.name() == plugin.name()).map(|_| panic!("Plugin with name '{}' already exists", plugin.name())); self.plugins.push(plugin); } pub fn remove_plugin(&mut self, plugin_name: &str) -> Option<Box<dyn Plugin>>{ let maybe_pos = self.plugins.iter().position(|plug| plug.name() == plugin_name); if let Some(pos) = maybe_pos { return Some(self.plugins.remove(pos)) } None } pub fn execute_all(&self) { self.plugins.iter().for_each(|plugin| { plugin.execute(); }) }}// Example usagepub fn main() { let mut manager = PluginManager::new(); manager.add_plugin(Box::new(MyPlugin::new("my_plugin "))); manager.add_plugin(Box::new(MyPlugin::new("my_plugin "))); manager.execute_all();}struct MyPlugin { name: String,}impl MyPlugin { pub fn new(name: &str) -> MyPlugin { Self { name: name.to_string(), } }}impl Plugin for MyPlugin { fn name(&self) -> &str { &self.name.as_str() } fn execute(&self) { println!("Execute plugin, {}!", self.name); }}
pub trait Plugin { // 1. Finish the trait fn name(&self) -> &str; fn execute(&self);}pub struct PluginManager { // 2. Finish the struct // Make fields public pub plugins: Vec<Box<dyn Plugin>>}// 3. Implement the PluginManagerimpl PluginManager { pub fn new() -> Self { Self { plugins: Vec::new() } } pub fn add_plugin(&mut self, plugin: Box<dyn Plugin>) { if self.plugins.iter().filter(|&p| p.name() == plugin.name()).collect::<Vec<_>>().is_empty() { self.plugins.push(plugin); } else { panic!("Plugin with name '{}' already exists", plugin.name()) } } pub fn remove_plugin(&mut self, name: &str) -> Option<Box<dyn Plugin>> { match self.plugins.iter().position(|p| p.name() == name) { Some(position) => Some(self.plugins.remove(position)), None => None } } pub fn execute_all(&self) { for plugin in self.plugins.iter() { plugin.execute() } }}pub struct MyPlugin { pub name: String}impl MyPlugin { fn new() -> Self { Self { name: String::new() } }}impl Plugin for MyPlugin { fn name(&self) -> &str { &self.name.as_str() } fn execute(&self) {}}// Example usagepub fn main() { let mut manager = PluginManager::new(); manager.add_plugin(Box::new(MyPlugin::new())); manager.execute_all();}
pub trait Plugin { fn name(&self) -> &str; fn execute(&self);}pub struct PluginManager { // 2. Finish the struct // Make fields public pub plugins: Vec<Box<dyn Plugin>>}// 3. Implement the PluginManagerimpl PluginManager { pub fn new() -> Self { Self { plugins: Vec::new() } } pub fn add_plugin(&mut self, np: Box<dyn Plugin>) { if self.plugins.iter().any(|p| p.name() == np.name()) { panic!("Plugin with name '{}' already exists", np.name()) } self.plugins.push(np); } pub fn remove_plugin(&mut self, name: &str) -> Option<Box<dyn Plugin>> { match self.plugins.iter().position(|p| p.name() == name) { Some(i) => Some(self.plugins.remove(i)), None => None } } pub fn execute_all(&self) { for plug in self.plugins.iter() { plug.execute() } }}pub struct MyPlugin { name: String,}impl MyPlugin { pub fn new() -> Self { Self { name: String::new() } }}impl Plugin for MyPlugin { fn name(&self) -> &str { &self.name } fn execute(&self) { () }}// Example usagepub fn main() { let mut manager = PluginManager::new(); manager.add_plugin(Box::new(MyPlugin::new())); manager.execute_all();}
pub trait Plugin { fn name(&self) -> &str; fn execute(&self);}pub struct PluginManager { pub plugins: Vec<Box<dyn Plugin>>}impl PluginManager { pub fn new() -> Self { PluginManager { plugins: vec![], } } pub fn add_plugin(&mut self, plugin: Box<dyn Plugin>) { match self.plugin_index(plugin.name()) { Some(_) => panic!("Plugin with name '{}' already exists", plugin.name()), None => self.plugins.push(plugin), } } pub fn remove_plugin(&mut self, name: &str) -> Option<Box<dyn Plugin>> { match self.plugin_index(&name) { Some(index) => Some(self.plugins.remove(index)), None => None, } } fn plugin_index(&self, name: &str) -> Option<usize> { self.plugins.iter().position(|p| p.name() == name) } pub fn execute_all(&self) { for plugin in &self.plugins { plugin.execute(); } }}
pub trait Plugin { // 1. Finish the trait fn name(&self) -> &str; fn execute(&self);}pub struct MyPlugin { name: String}impl MyPlugin { fn new() -> Self { Self { name: String::new()} }}impl Plugin for MyPlugin { fn name(&self) -> &str { &self.name } fn execute(&self) { println!("Executing") }}pub struct PluginManager { // 2. Finish the struct pub plugins: Vec<Box<dyn Plugin>> // Make fields public}// 3. Implement the PluginManagerimpl PluginManager { pub fn new() -> Self { Self { plugins: Vec::new()} } pub fn add_plugin(&mut self, plugin: Box<dyn Plugin>) { if self.plugins.iter().any(|p| p.name() == plugin.name() ) { panic!("Plugin with name '{}' already exists", plugin.name()) } self.plugins.push(plugin) } pub fn remove_plugin(&mut self, name: &str) -> Option<Box<dyn Plugin>> { let index = self.plugins.iter().position(|p| p.name() == name); match index { Some(i) => Some(self.plugins.remove(i)), None => None } } pub fn execute_all(&self) { self.plugins.iter().for_each(|p| p.execute()); }}// Example usagepub fn main() { let mut manager = PluginManager::new(); manager.add_plugin(Box::new(MyPlugin::new())); manager.execute_all();}
pub trait Plugin { // 1. Finish the trait fn name(&self) -> &str; fn execute(&self);}pub struct MyPlugin{ name: String}impl MyPlugin{ pub fn new()-> Self{ MyPlugin{name:"".to_string()} }}impl Plugin for MyPlugin{ fn name(&self) -> &str{ &self.name } fn execute(&self){ }}pub struct PluginManager { pub plugins: Vec<Box<dyn Plugin>>}// 3. Implement the PluginManagerimpl PluginManager { pub fn new() -> Self{ PluginManager{plugins:vec![]} } pub fn add_plugin(&mut self, new_p: Box<dyn Plugin>){ for pp in self.plugins.iter(){ if pp.name()==new_p.name(){ panic!("Plugin with name '{}' already exists",new_p.name()); } } self.plugins.push(new_p); } pub fn remove_plugin(&mut self, name: &str)->Option<Box<dyn Plugin>>{ let p = self.plugins.iter().position(|p| p.name() == name)?; return Some(self.plugins.remove(p)); } pub fn execute_all(&self){ self.plugins.iter().for_each(|x| x.execute()); } }// Example usagepub fn main() { let mut manager = PluginManager::new(); manager.add_plugin(Box::new(MyPlugin::new())); manager.execute_all();}
use std::collections::{ hash_map::Entry::{Occupied, Vacant}, HashMap,};pub trait Plugin { fn name(&self) -> &str; fn execute(&self);}#[derive(Default)]pub struct PluginManager { pub plugins: HashMap<String, Box<dyn Plugin>>,}impl PluginManager { pub fn new() -> Self { PluginManager::default() } pub fn add_plugin(&mut self, plugin: Box<dyn Plugin>) { match self.plugins.entry(plugin.name().to_string()) { Occupied(_) => panic!("Plugin with name '{}' already exists", plugin.name()), Vacant(entry) => entry.insert(plugin), }; } pub fn remove_plugin(&mut self, plugin_name: &str) -> Option<Box<dyn Plugin>> { self.plugins.remove(plugin_name) } pub fn execute_all(&self) { for plugin in self.plugins.values() { plugin.execute(); } }}
pub trait Plugin { fn name(&self) -> &str; fn execute(&self);}pub struct PluginManager { pub plugins: Vec<Box<dyn Plugin>>,}// 3. Implement the PluginManagerimpl PluginManager { pub fn new() -> Self { PluginManager { plugins: Vec::new(), } } pub fn add_plugin(&mut self, plugin: Box<dyn Plugin>) { if self.plugins.iter().any(|p| p.name() == plugin.name()) { panic!("Plugin with name '{}' already exists", plugin.name()); } self.plugins.push(plugin); } pub fn remove_plugin(&mut self, name: &str) -> Option<Box<dyn Plugin>>{ if let Some(index) = self.plugins.iter().position(|p| p.name() == name) { Some(self.plugins.remove(index)) } else { None } } pub fn execute_all(&self) { for plugin in &self.plugins { plugin.execute(); } }}// Example usage// pub fn main() {// let mut manager = PluginManager::new();// // manager.add_plugin(Box::new(MyPlugin::new()));// manager.execute_all();// }
pub trait Plugin { // 1. Finish the trait fn name(&self) -> &str; fn execute(&self);} pub struct PluginManager { // 2. Finish the struct // Make fields public pub plugins: Vec<Box<dyn Plugin>>,}// 3. Implement the PluginManagerimpl PluginManager { pub fn new() -> Self { PluginManager { plugins: Vec::new() } } pub fn add_plugin(&mut self, plugin :Box<dyn Plugin>) { if self.plugins.iter().any(|p| p.name() == plugin.name()) { panic!("Plugin with name '{}' already exists", plugin.name()); } self.plugins.push(plugin); } pub fn remove_plugin(&mut self, name: &str) -> Option<Box<dyn Plugin>> { if let Some(pos) = self.plugins.iter().position(|p| p.name().eq(name)) { return Some(self.plugins.remove(pos)); } None } pub fn execute_all(&self) { self.plugins.iter().for_each(|p| p.execute()); }}struct MyPlugin { name: String,}impl MyPlugin { fn new() -> Self { MyPlugin { name: String::from("My Plugin") } }}impl Plugin for MyPlugin { fn execute(&self) { println!("{} executing", self.name); } fn name(&self) -> &str { &self.name } }// Example usagepub fn main() { let mut manager = PluginManager::new(); manager.add_plugin(Box::new(MyPlugin::new())); manager.execute_all();}
pub trait Plugin { // 1. Finish the trait fn name(&self) -> &str; fn execute(&self);}pub struct PluginManager { // 2. Finish the struct // Make fields public pub plugins: Vec<Box<dyn Plugin>>,}// 3. Implement the PluginManagerimpl PluginManager { pub fn new() -> Self { PluginManager{ plugins: vec![] } } pub fn add_plugin(&mut self, plugin: Box<dyn Plugin>) { if self.plugins.iter().any(|p| p.name() == plugin.name()) { panic!("Plugin with name '{}' already exists", plugin.name()); } self.plugins.push(plugin); } pub fn remove_plugin(&mut self, name: &str) -> Option<Box<dyn Plugin>> { let index = self.plugins.iter().position(|p| p.name() == name)?; Some(self.plugins.swap_remove(index)) } pub fn execute_all(&self) { for plugin in self.plugins.iter() { plugin.execute(); } }}pub struct MyPlugin {}impl MyPlugin { pub fn new() -> Self { MyPlugin{} }}impl Plugin for MyPlugin { fn name(&self) -> &str { "MyPlugin" } fn execute(&self) { println!("Hello, {}!", self.name()); }}// Example usagepub fn main() { let mut manager = PluginManager::new(); manager.add_plugin(Box::new(MyPlugin::new())); manager.execute_all();}
pub trait Plugin { fn name(&self) -> &str; fn execute(&self);}pub struct PluginManager { pub plugins: Vec<Box<dyn Plugin>>,}// 3. Implement the PluginManagerimpl PluginManager { pub fn new() -> PluginManager { PluginManager { plugins: Vec::new(), } } pub fn add_plugin(&mut self, plugin: Box<dyn Plugin>) { if let Some(p) = self.plugins.iter().find(|p| p.name() == plugin.name()) { panic!("Plugin with name '{}' already exists", p.name()) } self.plugins.push(plugin); } pub fn remove_plugin(&mut self, name: &str) -> Option<Box<dyn Plugin>> { if let Some(index) = self.plugins.iter().position(|p| p.name() == name) { Some(self.plugins.remove(index)) } else { None } } pub fn execute_all(&self) { self.plugins.iter().for_each(|p| p.execute()); }}#[derive(Default)]pub struct MyPlugin { name: String,}impl MyPlugin { pub fn new() -> MyPlugin { MyPlugin::default() }}impl Plugin for MyPlugin { fn name(&self) -> &str { &self.name } fn execute(&self) { println!("Executing MyPlugin"); }}// Example usagepub fn main() { let mut manager = PluginManager::new(); manager.add_plugin(Box::new(MyPlugin::new())); manager.execute_all();}
pub trait Plugin { fn name(&self) -> &str; fn execute(&self);}#[derive(Default)]pub struct PluginManager { pub plugins: Vec<Box<dyn Plugin>>,}// 3. Implement the PluginManagerimpl PluginManager { pub fn new() -> Self { PluginManager { plugins: Vec::new(), } } pub fn add_plugin(&mut self, plugin: Box<dyn Plugin>) { match self.find_plugin(plugin.name()) { None => self.plugins.push(plugin), Some(_) => panic!("Plugin with name '{}' already exists", plugin.name()), } } pub fn remove_plugin(&mut self, name: &str) -> Option<Box<dyn Plugin>> { match self.find_plugin(name) { None => None, Some(index) => Some(self.plugins.remove(index)), } } pub fn execute_all(&self) { self.plugins.iter().for_each(|plugin| plugin.execute()); } fn find_plugin(&self, name: &str) -> Option<usize> { self.plugins.iter().position(|plugin| plugin.name() == name) }}#[derive(Default)]pub struct MyPlugin {}impl MyPlugin { pub fn new() -> Self { MyPlugin {} }}impl Plugin for MyPlugin { fn name(&self) -> &str { "MyPlugin" } fn execute(&self) {}}// Example usagepub fn main() { let mut manager = PluginManager::new(); manager.add_plugin(Box::new(MyPlugin::new())); manager.execute_all();}
pub trait Plugin { fn name(&self) -> &str; fn execute(&self);}pub struct PluginManager { pub plugins: Vec<Box<dyn Plugin>>,}// 3. Implement the PluginManagerimpl PluginManager { pub fn new() -> Self { return PluginManager { plugins: Vec::new() }; } pub fn add_plugin(&mut self, plugin: Box<dyn Plugin>) { let index = self.plugins.iter().position(|p| p.name() == plugin.name()); if None == index { self.plugins.push(plugin); } else { panic!("Plugin with name '{}' already exists", plugin.name()); } } pub fn remove_plugin(&mut self, name: &str) -> Option<Box<dyn Plugin>> { let index = self.plugins.iter().position(|p| p.name() == name)?; Some(self.plugins.remove(index)) } pub fn execute_all(&self) { for plugin in self.plugins.iter() { plugin.execute(); } }}pub struct MyPlugin;impl MyPlugin { pub fn new() -> Self { MyPlugin }}impl Plugin for MyPlugin { fn name(&self) -> &str { return "MyPlugin"; } fn execute(&self) { println!("MyPlugin executing") }}// Example usagepub fn main() { let mut manager = PluginManager::new(); manager.add_plugin(Box::new(MyPlugin::new())); manager.execute_all();}
pub trait Plugin { fn name(&self) -> &str; fn execute(&self);}pub struct PluginManager { pub plugins: Vec<Box<dyn Plugin>>,}impl PluginManager { pub fn new() -> Self { PluginManager { plugins: vec![] } } pub fn add_plugin(&mut self, plugin: Box<dyn Plugin>) { let plugins: Vec<&str> = self.plugins.iter().map(|x| x.name()).collect(); if plugins.contains(&plugin.name()) { panic!("Plugin with name '{}' already exists", plugin.name()); } else { self.plugins.push(plugin); } } pub fn remove_plugin(&mut self, plugin: &str) -> Option<Box<dyn Plugin>> { let p = self.plugins.iter().position(|p| p.name() == plugin)?; let removed = self.plugins.remove(p); Some(removed) } pub fn execute_all(&self) { for plugin in &self.plugins { plugin.execute(); } }}pub struct MyPlugin {}impl MyPlugin { pub fn new() -> Self { Self {} }}impl Plugin for MyPlugin { fn name(&self) -> &str { "MyPlugin" } fn execute(&self) {}}// Example usagepub fn main() { let mut manager = PluginManager::new(); manager.add_plugin(Box::new(MyPlugin::new())); manager.execute_all();}
use std::vec::Vec;pub trait Plugin { fn name(&self) -> &str; fn execute(&self);}pub struct PluginManager { pub plugins: Vec<Box<dyn Plugin>>,}// 3. Implement the PluginManagerimpl PluginManager { pub fn new() -> Self { Self { plugins: Vec::new(), } } pub fn add_plugin(&mut self, plugin: Box<dyn Plugin>) { assert!(!self.plugins.iter().any(|p| p.name() == plugin.name()), "Plugin with name '{}' already exists", plugin.name()); self.plugins.push(plugin); } pub fn remove_plugin(&mut self, plugin: &str) -> Option<Box<dyn Plugin>> { let index = self.plugins.iter().position(|p| p.name() == plugin)?; let removed = self.plugins.remove(index); Some(removed) } pub fn execute_all(&self) { self.plugins.iter().for_each(|plugin| plugin.execute()); }}pub struct MyPlugin {}impl MyPlugin { pub fn new() -> Self { Self {} }}impl Plugin for MyPlugin { fn name(&self) -> &str { "MyPlugin" } fn execute(&self) {}}// Example usagepub fn main() { let mut manager = PluginManager::new(); manager.add_plugin(Box::new(MyPlugin::new())); manager.execute_all();}
pub trait Plugin { fn name(&self) -> &str; fn execute(&self);}pub struct PluginManager { pub plugins: Vec<Box<dyn Plugin>>}// 3. Implement the PluginManagerimpl PluginManager { pub fn new() -> Self { Self { plugins: Vec::new() } } pub fn add_plugin(&mut self, plugin: Box<dyn Plugin>) { assert!(!self.plugins.iter().any(|p| p.name() == plugin.name()), "{}", format!("Plugin with name '{}' already exists", plugin.name())); self.plugins.push(plugin); } pub fn execute_all(&self) { self.plugins.iter().for_each(|p| p.execute()); } pub fn remove_plugin(&mut self, plugin: &str) -> Option<Box<dyn Plugin>> { let p = self.plugins.iter().position(|p| p.name() == plugin)?; Some(self.plugins.remove(p)) }}pub struct MyPlugin { name: String}impl MyPlugin { pub fn new() -> Self { Self { name: String::new() } }}impl Plugin for MyPlugin { fn name(&self) -> &str { &self.name } fn execute(&self) { }}// Example usagepub fn main() { let mut manager = PluginManager::new(); manager.add_plugin(Box::new(MyPlugin::new())); manager.execute_all();}
pub trait Plugin { fn name(&self) -> &str; fn execute(&self);}pub struct PluginManager { pub plugins: Vec<Box<dyn Plugin>>,}impl PluginManager { pub fn new() -> Self { PluginManager { plugins: Vec::<Box<dyn Plugin>>::new(), } } pub fn add_plugin(&mut self, plugin: Box<dyn Plugin>) { if self.plugins.iter().map(|p| p.name()).any(|name| name == plugin.name()) { panic!("Plugin with name '{}' already exists", plugin.name()); } self.plugins.push(plugin); } pub fn remove_plugin(&mut self, name: &str) -> Option<Box<dyn Plugin>> { if self.plugins.iter().map(|p| p.name()).any(|n| n != name) { panic!("Plugin with name '{}' does not exist", name); } let p = self.plugins.iter().position(|p| p.name() == name)?; Some(self.plugins.remove(p)) } pub fn execute_all(&self) { self.plugins.iter().for_each(|plugin| plugin.execute()); }}
pub trait Plugin { // 1. Finish the trait fn name(&self) -> &str; fn execute(&self);}pub struct PluginManager { // 2. Finish the struct // Make fields public pub plugins: Vec<Box<dyn Plugin>>,}// 3. Implement the PluginManagerimpl PluginManager { pub fn new() -> Self { Self { plugins: Vec::new(), } } pub fn add_plugin(&mut self, plugin: Box<dyn Plugin>) { if self .plugins .iter() .map(|p| p.name()) .any(|name| name == plugin.name()) { panic!("Plugin with name '{}' already exists", plugin.name()); } self.plugins.push(plugin); } pub fn remove_plugin(&mut self, name: &str) -> Option<Box<dyn Plugin>> { let p = self.plugins.iter().position(|p| p.name() == name)?; Some(self.plugins.remove(p)) } pub fn execute_all(&self) { self.plugins.iter().for_each(|plugin| plugin.execute()); }}
pub trait Plugin { // 1. Finish the trait fn name(&self) -> &str; fn execute(&self);}pub struct PluginManager { // 2. Finish the struct // Make fields public pub plugins: Vec<Box<dyn Plugin>>}// 3. Implement the PluginManagerimpl PluginManager { pub fn new() -> Self { PluginManager{ plugins: Vec::new() } } pub fn add_plugin(&mut self, plugin: Box<dyn Plugin>) { if self.plugins.iter().any(|p| p.name() == plugin.name()){ panic!("{}", format!("Plugin with name '{}' already exists", plugin.name())) } self.plugins.push(plugin); } pub fn remove_plugin(&mut self, plugin_name: &str) -> Option<Box<dyn Plugin>> { for (i, plugin) in self.plugins.iter().enumerate() { if plugin.name() == plugin_name { return Some(self.plugins.remove(i)); } } None } pub fn execute_all(&self) { let _ = self.plugins.iter().map(|p| p.execute()); }}pub struct MyPlugin { name: String}impl MyPlugin { fn new() -> MyPlugin { MyPlugin{ name: String::from("MyPlugin") } }}impl Plugin for MyPlugin { fn name(&self) -> &str { &self.name } fn execute(&self) { println!("execute.") }}// Example usagepub fn main() { let mut manager = PluginManager::new(); manager.add_plugin(Box::new(MyPlugin::new())); manager.execute_all();}
pub trait Plugin { fn name(&self) -> &str; fn execute(&self);}pub struct MyPlugin { name: String,}impl MyPlugin { pub fn new() -> Self { MyPlugin {name: "geebly beebly".to_string()} }}impl Plugin for MyPlugin { fn name(&self) -> &str { &self.name } fn execute(&self) { println!("executed") }}pub struct PluginManager { pub plugins: Vec<Box<dyn Plugin>>}// 3. Implement the PluginManagerimpl PluginManager { pub fn new() -> Self { PluginManager {plugins: vec![]} } pub fn add_plugin(&mut self, p: Box<dyn Plugin>) { if self.plugins.iter().any(|plug| p.name() == plug.name()){ panic!("{}", format!("Plugin with name '{}' already exists", p.name())) } self.plugins.push(p); } pub fn remove_plugin(&mut self, p: &str) -> Option<Box<dyn Plugin>>{ let mut index = 0; let mut found = false; for i in 0..self.plugins.len() { if self.plugins[i].name() == p { index = i; found = true } } if !found { None } else { Some(self.plugins.remove(index)) } } pub fn execute_all(&self) { self.plugins.iter().for_each(|x| x.execute()) }}// Example usagepub fn main() { let mut manager = PluginManager::new(); manager.add_plugin(Box::new(MyPlugin::new())); manager.execute_all();}
pub trait Plugin { // 1. Finish the trait fn name(&self) -> &str; fn execute(&self);}pub struct PluginManager { // 2. Finish the struct // Make fields public pub plugins: Vec<Box<dyn Plugin>>,}// 3. Implement the PluginManagerimpl PluginManager { pub fn new() -> Self { Self { plugins: vec![] } } pub fn add_plugin(&mut self, plugin: Box<dyn Plugin>) { if self.plugins.iter().any(|p| p.name() == plugin.name()) { panic!("Plugin with name '{}' already exists", plugin.name()); } self.plugins.push(plugin); } pub fn remove_plugin(&mut self, name: &str) -> Option<Box<dyn Plugin>> { if let Some(i) = self.plugins.iter().position(|p| p.name() == name) { Some(self.plugins.remove(i)) } else { None } } pub fn execute_all(&self) { self.plugins.iter().for_each(|p| p.execute()); }}struct MyPlugin { pub name: String,}impl MyPlugin { fn new() -> Self { Self { name: "bob".to_string() } }}impl Plugin for MyPlugin { fn name(&self) -> &str { &self.name } fn execute(&self) { println!("Howdy"); }}// Example usagepub fn main() { let mut manager = PluginManager::new(); manager.add_plugin(Box::new(MyPlugin::new())); manager.execute_all();}
pub trait Plugin { // 1. Finish the trait fn name(&self) -> &str; fn execute(&self);}pub struct PluginManager { // 2. Finish the struct // Make fields public pub plugins: Vec<Box<dyn Plugin>>,}// 3. Implement the PluginManagerimpl PluginManager { pub fn new() -> Self { Self { plugins: Vec::new(), } } pub fn add_plugin(&mut self, plugin: Box<dyn Plugin>) { let name = plugin.name(); let has_same_name = self.plugins.iter().any(|p| p.name() == name); if has_same_name { panic!("Plugin with name '{}' already exists", name); } self.plugins.push(plugin); } pub fn remove_plugin(&mut self, plugin_name: &str) -> Option<Box<dyn Plugin>> { let find = self.plugins.iter().position(|p| p.name() == plugin_name); if let Some(index) = find { Some(self.plugins.remove(index)) } else { None } } pub fn execute_all(&self) { for plugin in self.plugins.iter() { plugin.execute(); } }}// // Example usage// pub fn main() {// let mut manager = PluginManager::new();// manager.add_plugin(Box::new(MyPlugin::new()));// manager.execute_all();// }