tool_registry.rs

 1use std::sync::Arc;
 2
 3use collections::HashMap;
 4use derive_more::{Deref, DerefMut};
 5use gpui::Global;
 6use gpui::{App, ReadGlobal};
 7use parking_lot::RwLock;
 8
 9use crate::Tool;
10
11#[derive(Default, Deref, DerefMut)]
12struct GlobalToolRegistry(Arc<ToolRegistry>);
13
14impl Global for GlobalToolRegistry {}
15
16#[derive(Default)]
17struct ToolRegistryState {
18    tools: HashMap<Arc<str>, Arc<dyn Tool>>,
19}
20
21#[derive(Default)]
22pub struct ToolRegistry {
23    state: RwLock<ToolRegistryState>,
24}
25
26impl ToolRegistry {
27    /// Returns the global [`ToolRegistry`].
28    pub fn global(cx: &App) -> Arc<Self> {
29        GlobalToolRegistry::global(cx).0.clone()
30    }
31
32    /// Returns the global [`ToolRegistry`].
33    ///
34    /// Inserts a default [`ToolRegistry`] if one does not yet exist.
35    pub fn default_global(cx: &mut App) -> Arc<Self> {
36        cx.default_global::<GlobalToolRegistry>().0.clone()
37    }
38
39    pub fn new() -> Arc<Self> {
40        Arc::new(Self {
41            state: RwLock::new(ToolRegistryState {
42                tools: HashMap::default(),
43            }),
44        })
45    }
46
47    /// Registers the provided [`Tool`].
48    pub fn register_tool(&self, tool: impl Tool) {
49        let mut state = self.state.write();
50        let tool_name: Arc<str> = tool.name().into();
51        state.tools.insert(tool_name, Arc::new(tool));
52    }
53
54    /// Unregisters the provided [`Tool`].
55    pub fn unregister_tool(&self, tool: impl Tool) {
56        self.unregister_tool_by_name(tool.name().as_str())
57    }
58
59    /// Unregisters the tool with the given name.
60    pub fn unregister_tool_by_name(&self, tool_name: &str) {
61        let mut state = self.state.write();
62        state.tools.remove(tool_name);
63    }
64
65    /// Returns the list of tools in the registry.
66    pub fn tools(&self) -> Vec<Arc<dyn Tool>> {
67        self.state.read().tools.values().cloned().collect()
68    }
69
70    /// Returns the [`Tool`] with the given name.
71    pub fn tool(&self, name: &str) -> Option<Arc<dyn Tool>> {
72        self.state.read().tools.get(name).cloned()
73    }
74}