use std::collections::BTreeMap;
use thiserror::Error;
use crate::erased::{DynTool, ToolDescriptor, TypedTool};
use crate::handler::ToolHandler;
#[derive(Default)]
pub struct ToolSet {
tools: BTreeMap<String, Box<dyn DynTool>>,
}
impl ToolSet {
pub fn new() -> Self {
Self::default()
}
pub fn register<H: ToolHandler + 'static>(&mut self, handler: H) -> Result<(), RegistryError> {
self.register_dyn(Box::new(TypedTool::new(handler)))
}
pub fn register_dyn(&mut self, tool: Box<dyn DynTool>) -> Result<(), RegistryError> {
let name = tool.name().to_owned();
if self.tools.contains_key(&name) {
return Err(RegistryError::DuplicateName { name });
}
self.tools.insert(name, tool);
Ok(())
}
pub fn get(&self, name: &str) -> Option<&dyn DynTool> {
self.tools.get(name).map(Box::as_ref)
}
pub fn len(&self) -> usize {
self.tools.len()
}
pub fn is_empty(&self) -> bool {
self.tools.is_empty()
}
pub fn tools(&self) -> impl Iterator<Item = &dyn DynTool> {
self.tools.values().map(Box::as_ref)
}
pub fn descriptors(&self) -> Vec<ToolDescriptor> {
self.tools().map(DynTool::descriptor).collect()
}
}
#[derive(Debug, Error, PartialEq, Eq)]
pub enum RegistryError {
#[error("a tool named `{name}` is already registered")]
DuplicateName {
name: String,
},
}