pub struct CommandRegistry { /* private fields */ }Expand description
Central registry for commands and their handlers
The registry stores all registered commands along with their definitions and handlers. It provides efficient lookup by both command name and alias.
§Thread Safety
The registry is designed to be constructed once during application startup
and then shared immutably across the application. For multi-threaded access,
wrap it in Arc<CommandRegistry>.
§Example
use dynamic_cli::registry::CommandRegistry;
use dynamic_cli::config::schema::CommandDefinition;
use dynamic_cli::executor::CommandHandler;
use std::collections::HashMap;
let mut registry = CommandRegistry::new();
// Register commands during initialization
registry.register_sync(definition, Box::new(TestCommand))?;
// Use throughout the application
if let Some(handler) = registry.get_handler_sync("test") {
// Execute the command
}Implementations§
Source§impl CommandRegistry
impl CommandRegistry
Sourcepub fn new() -> Self
pub fn new() -> Self
Create a new empty registry
§Example
use dynamic_cli::registry::CommandRegistry;
let registry = CommandRegistry::new();
assert_eq!(registry.list_commands().len(), 0);Sourcepub fn register_sync(
&mut self,
definition: CommandDefinition,
handler: Box<dyn CommandHandler>,
) -> Result<()>
pub fn register_sync( &mut self, definition: CommandDefinition, handler: Box<dyn CommandHandler>, ) -> Result<()>
Register a command with its (sync) handler
This method registers a command definition along with its handler. It also registers all aliases for the command.
Renamed from register() in v0.5.0 for symmetry with
register_async. register() remains
available as a deprecated alias until v1.0.0 (DD-022).
§Arguments
definition- The command definition from the configurationhandler- The handler implementation for this command
§Returns
Ok(())if registration succeedsErr(RegistryError)if:- A command with the same name is already registered (sync or async)
- An alias conflicts with an existing command or alias
§Errors
RegistryError::DuplicateRegistrationif the command name already existsRegistryError::DuplicateAliasif an alias is already in use
§Example
use dynamic_cli::registry::CommandRegistry;
use dynamic_cli::config::schema::CommandDefinition;
use dynamic_cli::executor::CommandHandler;
use std::collections::HashMap;
let mut registry = CommandRegistry::new();
let definition = CommandDefinition {
name: "simulate".to_string(),
aliases: vec!["sim".to_string(), "run".to_string()],
description: "Run simulation".to_string(),
required: false,
arguments: vec![],
options: vec![],
implementation: "sim_handler".to_string(),
};
struct SimCommand;
impl CommandHandler for SimCommand {
fn execute(
&self,
_: &mut dyn dynamic_cli::context::ExecutionContext,
_: &HashMap<String, String>,
) -> dynamic_cli::Result<()> {
Ok(())
}
}
// Register the command
registry.register_sync(definition, Box::new(SimCommand))?;
// Can now access by name or alias
assert!(registry.get_handler_sync("simulate").is_some());
assert_eq!(registry.resolve_name("sim"), Some("simulate"));Sourcepub fn register(
&mut self,
definition: CommandDefinition,
handler: Box<dyn CommandHandler>,
) -> Result<()>
👎Deprecated since 0.5.0: renamed to register_sync for symmetry with register_async; will be removed in 1.0.0
pub fn register( &mut self, definition: CommandDefinition, handler: Box<dyn CommandHandler>, ) -> Result<()>
renamed to register_sync for symmetry with register_async; will be removed in 1.0.0
Deprecated alias for register_sync.
Kept for backward compatibility with pre-0.5.0 consumers (e.g.
chrom-rs). Scheduled for removal in v1.0.0, batched with the other
breaking changes tracked in the v1.0.0 API cleanup issue.
Sourcepub fn register_async(
&mut self,
definition: CommandDefinition,
handler: Box<dyn AsyncCommandHandler>,
) -> Result<()>
pub fn register_async( &mut self, definition: CommandDefinition, handler: Box<dyn AsyncCommandHandler>, ) -> Result<()>
Register a command with its async handler (DD-022)
Additive counterpart of register_sync —
same conflict-detection rules (checked against both sync and async
registrations sharing the unified internal storage, plus aliases),
same alias handling.
§Errors
RegistryError::DuplicateRegistrationif the command name already existsRegistryError::DuplicateAliasif an alias is already in use
§Example
use dynamic_cli::registry::CommandRegistry;
use dynamic_cli::config::schema::CommandDefinition;
use dynamic_cli::executor::AsyncCommandHandler;
use std::collections::HashMap;
use async_trait::async_trait;
let mut registry = CommandRegistry::new();
let definition = CommandDefinition {
name: "fetch".to_string(),
aliases: vec![],
description: "Fetch remote data".to_string(),
required: false,
arguments: vec![],
options: vec![],
implementation: "fetch_handler".to_string(),
};
struct FetchCommand;
#[async_trait]
impl AsyncCommandHandler for FetchCommand {
async fn execute(
&self,
_: &mut dyn dynamic_cli::context::ExecutionContext,
_: &HashMap<String, String>,
) -> dynamic_cli::Result<()> {
Ok(())
}
}
registry.register_async(definition, Box::new(FetchCommand))?;
assert!(registry.get_handler_async("fetch").is_some());Sourcepub fn resolve_name(&self, name: &str) -> Option<&str>
pub fn resolve_name(&self, name: &str) -> Option<&str>
Resolve a name (command or alias) to the canonical command name
This method checks if the given name is either:
- A registered command name (returns the name itself)
- An alias (returns the canonical command name)
§Arguments
name- The name or alias to resolve
§Returns
Some(&str)- The canonical command nameNone- If the name is not registered
§Example
use dynamic_cli::registry::CommandRegistry;
let mut registry = CommandRegistry::new();
// Resolve command name
assert_eq!(registry.resolve_name("hello"), Some("hello"));
// Resolve alias
assert_eq!(registry.resolve_name("hi"), Some("hello"));
// Unknown name
assert_eq!(registry.resolve_name("unknown"), None);Sourcepub fn get_definition(&self, name: &str) -> Option<&CommandDefinition>
pub fn get_definition(&self, name: &str) -> Option<&CommandDefinition>
Get the definition of a command by name or alias
§Arguments
name- The command name or alias
§Returns
Some(&CommandDefinition)if the command existsNoneif the command is not registered
§Example
// Get by name
if let Some(def) = registry.get_definition("test") {
assert_eq!(def.name, "test");
assert_eq!(def.description, "Test command");
}
// Get by alias
if let Some(def) = registry.get_definition("t") {
assert_eq!(def.name, "test");
}Sourcepub fn get_handler_sync(&self, name: &str) -> Option<&dyn CommandHandler>
pub fn get_handler_sync(&self, name: &str) -> Option<&dyn CommandHandler>
Get the (sync) handler of a command by name or alias
This is the primary method used during CLI/REPL dispatch to
retrieve the handler that will execute the command. Returns None
both when the name isn’t registered at all, and when it resolves to
an async handler (query get_handler_async
instead in that case) — dispatch sites try both in sequence.
Renamed from get_handler() in v0.5.0 for symmetry with
get_handler_async. get_handler()
remains available as a deprecated alias until v1.0.0 (DD-022).
§Arguments
name- The command name or alias
§Returns
Some(&dyn CommandHandler)if a sync handler is registered under this nameNoneif unregistered, or if registered as an async handler
§Example
// Get handler by name
if let Some(handler) = registry.get_handler_sync("exec") {
// Use handler for execution
}
// Get handler by alias
if let Some(handler) = registry.get_handler_sync("x") {
// Same handler
}Sourcepub fn get_handler(&self, name: &str) -> Option<&dyn CommandHandler>
👎Deprecated since 0.5.0: renamed to get_handler_sync for symmetry with get_handler_async; will be removed in 1.0.0
pub fn get_handler(&self, name: &str) -> Option<&dyn CommandHandler>
renamed to get_handler_sync for symmetry with get_handler_async; will be removed in 1.0.0
Deprecated alias for get_handler_sync.
Scheduled for removal in v1.0.0.
Sourcepub fn get_handler_async(&self, name: &str) -> Option<&dyn AsyncCommandHandler>
pub fn get_handler_async(&self, name: &str) -> Option<&dyn AsyncCommandHandler>
Get the async handler of a command by name or alias (DD-022)
Additive counterpart of get_handler_sync.
Returns None both when the name isn’t registered at all, and when
it resolves to a sync handler.
§Example
assert!(registry.get_handler_async("fetch").is_some());
assert!(registry.get_handler_sync("fetch").is_none()); // wrong accessorSourcepub fn list_commands(&self) -> Vec<&CommandDefinition>
pub fn list_commands(&self) -> Vec<&CommandDefinition>
List all registered command definitions
Returns a vector of references to all command definitions in the registry. The order is not guaranteed.
§Returns
Vector of command definition references
§Example
let commands = registry.list_commands();
assert_eq!(commands.len(), 2);
// Use for help text, command completion, etc.
for cmd in commands {
println!("{}: {}", cmd.name, cmd.description);
}Sourcepub fn len(&self) -> usize
pub fn len(&self) -> usize
Get the number of registered commands
§Example
use dynamic_cli::registry::CommandRegistry;
let registry = CommandRegistry::new();
assert_eq!(registry.len(), 0);Trait Implementations§
Auto Trait Implementations§
impl !RefUnwindSafe for CommandRegistry
impl !UnwindSafe for CommandRegistry
impl Freeze for CommandRegistry
impl Send for CommandRegistry
impl Sync for CommandRegistry
impl Unpin for CommandRegistry
impl UnsafeUnpin for CommandRegistry
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more