use std::{any::Any, collections::HashMap};
pub trait WitCommand: Send + Sync + 'static {
type Response: Send + Sync + 'static;
fn command_name(&self) -> &'static str;
fn as_any(&self) -> &dyn Any;
}
pub trait WitCommandHandler<C: WitCommand>: Send + Sync {
fn execute(&mut self, command: &C) -> Result<C::Response, String>;
}
pub struct WitCommandDispatcher {
handlers: HashMap<&'static str, Box<dyn Any + Send + Sync>>,
}
impl WitCommandDispatcher {
pub fn new() -> Self {
Self {
handlers: HashMap::new(),
}
}
pub fn register<C: WitCommand>(
&mut self,
command_name: &'static str,
handler: Box<dyn WitCommandHandler<C>>,
) {
self.handlers.insert(command_name, Box::new(handler));
}
pub fn dispatch<C: WitCommand>(&mut self, command: &C) -> Result<C::Response, String> {
let name = command.command_name();
let handler = self
.handlers
.get_mut(name)
.ok_or_else(|| format!("No handler registered for command: {}", name))?;
let handler = handler
.downcast_mut::<Box<dyn WitCommandHandler<C>>>()
.ok_or_else(|| format!("Handler type mismatch for command: {}", name))?;
handler.execute(command)
}
}
impl Default for WitCommandDispatcher {
fn default() -> Self {
Self::new()
}
}
pub trait WitInterface: Send + Sync {
fn interface_name(&self) -> &'static str;
fn register_handlers(&self, dispatcher: &mut WitCommandDispatcher);
}
pub struct CompositeWitInterface {
interfaces: Vec<Box<dyn WitInterface>>,
}
impl CompositeWitInterface {
pub fn new() -> Self {
Self {
interfaces: Vec::new(),
}
}
pub fn add_interface(&mut self, interface: Box<dyn WitInterface>) {
self.interfaces.push(interface);
}
pub fn register_all(&self, dispatcher: &mut WitCommandDispatcher) {
for interface in &self.interfaces {
interface.register_handlers(dispatcher);
}
}
}
impl Default for CompositeWitInterface {
fn default() -> Self {
Self::new()
}
}