registry.rs

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