registry.rs

 1use std::sync::Arc;
 2
 3use anyhow::Result;
 4use collections::HashMap;
 5use gpui::{AppContext, AsyncAppContext, ReadGlobal};
 6use gpui::{Global, Task};
 7use parking_lot::RwLock;
 8
 9use crate::ContextServer;
10
11pub type ContextServerFactory =
12    Arc<dyn Fn(&AsyncAppContext) -> Task<Result<Arc<dyn ContextServer>>> + Send + Sync + 'static>;
13
14#[derive(Default)]
15struct GlobalContextServerFactoryRegistry(Arc<ContextServerFactoryRegistry>);
16
17impl Global for GlobalContextServerFactoryRegistry {}
18
19#[derive(Default)]
20struct ContextServerFactoryRegistryState {
21    context_servers: HashMap<Arc<str>, ContextServerFactory>,
22}
23
24#[derive(Default)]
25pub struct ContextServerFactoryRegistry {
26    state: RwLock<ContextServerFactoryRegistryState>,
27}
28
29impl ContextServerFactoryRegistry {
30    /// Returns the global [`ContextServerFactoryRegistry`].
31    pub fn global(cx: &AppContext) -> Arc<Self> {
32        GlobalContextServerFactoryRegistry::global(cx).0.clone()
33    }
34
35    /// Returns the global [`ContextServerFactoryRegistry`].
36    ///
37    /// Inserts a default [`ContextServerFactoryRegistry`] if one does not yet exist.
38    pub fn default_global(cx: &mut AppContext) -> Arc<Self> {
39        cx.default_global::<GlobalContextServerFactoryRegistry>()
40            .0
41            .clone()
42    }
43
44    pub fn new() -> Arc<Self> {
45        Arc::new(Self {
46            state: RwLock::new(ContextServerFactoryRegistryState {
47                context_servers: HashMap::default(),
48            }),
49        })
50    }
51
52    pub fn context_server_factories(&self) -> Vec<(Arc<str>, ContextServerFactory)> {
53        self.state
54            .read()
55            .context_servers
56            .iter()
57            .map(|(id, factory)| (id.clone(), factory.clone()))
58            .collect()
59    }
60
61    /// Registers the provided [`ContextServerFactory`].
62    pub fn register_server_factory(&self, id: Arc<str>, factory: ContextServerFactory) {
63        let mut state = self.state.write();
64        state.context_servers.insert(id, factory);
65    }
66
67    /// Unregisters the [`ContextServerFactory`] for the server with the given ID.
68    pub fn unregister_server_factory_by_id(&self, server_id: &str) {
69        let mut state = self.state.write();
70        state.context_servers.remove(server_id);
71    }
72}