registry.rs

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