registry.rs

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