Skip to main content

Plugin

Trait Plugin 

Source
pub trait Plugin: Send + Sync {
    // Required methods
    fn name(&self) -> &str;
    fn version(&self) -> &str;
    fn description(&self) -> &str;
    fn handlers(&self) -> Vec<(String, Box<dyn CommandHandler>)>;
}
Expand description

Extension point for grouping related command handlers.

A plugin declares its metadata and the handlers it provides. The framework validates and registers those handlers into the [CommandRegistry] during [CliBuilder::build()]. The plugin never has direct access to the registry.

§Contract

  • Plugin::handlers returns (implementation_name, handler) pairs.
  • Each implementation_name must match the implementation field of a command declared in the YAML config — exactly as with [CliBuilder::register_handler].
  • The YAML config remains the sole source of truth for command definitions. A plugin cannot inject commands that are not declared in the config.

§Object safety

This trait is intentionally object-safe (dyn Plugin is valid). Do not add methods with generic type parameters.

§Thread safety

Implementations must be Send + Sync.

§Example

use dynamic_cli::plugin::{Plugin, SystemPlugin};
use dynamic_cli::executor::CommandHandler;
use dynamic_cli::context::ExecutionContext;
use std::collections::HashMap;

struct MyPlugin;

impl Plugin for MyPlugin {
    fn name(&self) -> &str { "my-plugin" }
    fn version(&self) -> &str { "1.0.0" }
    fn description(&self) -> &str { "My custom plugin" }

    fn handlers(&self) -> Vec<(String, Box<dyn CommandHandler>)> {
        struct MyHandler;
        impl CommandHandler for MyHandler {
            fn execute(
                &self,
                _ctx: &mut dyn ExecutionContext,
                _args: &HashMap<String, String>,
            ) -> dynamic_cli::Result<()> {
                println!("executed");
                Ok(())
            }
        }
        vec![("my_handler".to_string(), Box::new(MyHandler))]
    }
}

// Trait object usage (object-safe)
let plugin: Box<dyn Plugin> = Box::new(MyPlugin);
assert_eq!(plugin.name(), "my-plugin");
assert_eq!(plugin.version(), "1.0.0");
assert_eq!(plugin.handlers().len(), 1);

Required Methods§

Source

fn name(&self) -> &str

Short identifier for this plugin (e.g. "system", "greet").

Source

fn version(&self) -> &str

Semantic version string (e.g. "1.0.0").

Source

fn description(&self) -> &str

Human-readable description of what this plugin provides.

Source

fn handlers(&self) -> Vec<(String, Box<dyn CommandHandler>)>

Returns the handlers this plugin contributes.

Each element is (implementation_name, handler) where implementation_name matches the implementation field in the YAML config for the corresponding command.

Dyn Compatibility§

This trait is dyn compatible.

In older versions of Rust, dyn compatibility was called "object safety".

Implementors§