use anyhow::Result;
use module_registry::{Module, ModuleRegistry};
trait Plugin: Module {
fn initialize(&self) -> Result<()>;
fn execute(&self, input: &str) -> Result<String>;
fn version(&self) -> &str;
}
struct EchoPlugin {
name: String,
version: String,
}
impl Module for EchoPlugin {
fn name(&self) -> &str {
&self.name
}
fn module_type(&self) -> &str {
"plugin"
}
}
impl Plugin for EchoPlugin {
fn initialize(&self) -> Result<()> {
println!(" Initializing {} v{}", self.name, self.version);
Ok(())
}
fn execute(&self, input: &str) -> Result<String> {
Ok(format!("[Echo] {}", input))
}
fn version(&self) -> &str {
&self.version
}
}
struct ReversePlugin {
name: String,
}
impl Module for ReversePlugin {
fn name(&self) -> &str {
&self.name
}
fn module_type(&self) -> &str {
"plugin"
}
}
impl Plugin for ReversePlugin {
fn initialize(&self) -> Result<()> {
println!(" Initializing {}", self.name);
Ok(())
}
fn execute(&self, input: &str) -> Result<String> {
Ok(input.chars().rev().collect())
}
fn version(&self) -> &str {
"1.0.0"
}
}
fn create_echo_plugin() -> Result<Box<dyn std::any::Any + Send + Sync>> {
Ok(Box::new(Box::new(EchoPlugin {
name: "echo".to_string(),
version: "1.0.0".to_string(),
}) as Box<dyn Plugin>))
}
fn create_reverse_plugin() -> Result<Box<dyn std::any::Any + Send + Sync>> {
Ok(Box::new(Box::new(ReversePlugin {
name: "reverse".to_string(),
}) as Box<dyn Plugin>))
}
fn main() -> Result<()> {
println!("=== Module Registry: Plugin System Example ===\n");
println!("1. Creating Plugin Registry");
println!("----------------------------");
let registry = ModuleRegistry::new();
println!("Registry created with {} plugins", registry.count());
println!("\n2. Registering Plugins");
println!("----------------------");
registry.register_with_metadata(
"echo",
"plugin",
"create_echo_plugin",
"example::plugins::echo",
"EchoPlugin",
create_echo_plugin,
);
registry.register_with_metadata(
"reverse",
"plugin",
"create_reverse_plugin",
"example::plugins::reverse",
"ReversePlugin",
create_reverse_plugin,
);
println!("Registered {} plugins", registry.count());
println!("\n3. Available Plugins");
println!("--------------------");
for plugin_name in registry.list_modules() {
if let Some(metadata) = registry.get_metadata(&plugin_name) {
println!(" - {} ({})", metadata.name, metadata.module_type);
println!(" Struct: {}", metadata.struct_name);
println!(" Path: {}", metadata.module_path);
}
}
println!("\n4. Initializing Plugins");
println!("-----------------------");
for plugin_name in registry.list_modules() {
let any_module = registry.create_any(&plugin_name)?;
let plugin = any_module
.downcast::<Box<dyn Plugin>>()
.map_err(|_| anyhow::anyhow!("Type mismatch"))?;
plugin.initialize()?;
}
println!("\n5. Executing Plugins");
println!("--------------------");
let test_input = "Hello, World!";
println!("Input: \"{}\"", test_input);
for plugin_name in registry.list_modules() {
let any_module = registry.create_any(&plugin_name)?;
let plugin = any_module
.downcast::<Box<dyn Plugin>>()
.map_err(|_| anyhow::anyhow!("Type mismatch"))?;
let output = plugin.execute(test_input)?;
println!(" {} → \"{}\"", plugin.name(), output);
}
println!("\n6. Plugin Existence Checks");
println!("--------------------------");
println!("Has 'echo' plugin? {}", registry.has_module("echo"));
println!("Has 'reverse' plugin? {}", registry.has_module("reverse"));
println!("Has 'missing' plugin? {}", registry.has_module("missing"));
println!("\n7. Using Global Registry");
println!("------------------------");
let global = ModuleRegistry::global();
global.register("global_echo", "plugin", create_echo_plugin);
println!("Global registry has {} modules", global.count());
let any_module = global.create_any("global_echo")?;
let plugin = any_module
.downcast::<Box<dyn Plugin>>()
.map_err(|_| anyhow::anyhow!("Type mismatch"))?;
let result = plugin.execute("Global test")?;
println!("Global plugin output: {}", result);
global.clear();
println!("\n=== Example completed successfully ===");
Ok(())
}