registry.rs

 1use std::sync::Arc;
 2
 3use anyhow::Result;
 4use collections::HashMap;
 5use extension::ContextServerConfiguration;
 6use gpui::{App, AppContext as _, AsyncApp, Entity, Global, ReadGlobal, Task};
 7use project::Project;
 8
 9use crate::ServerCommand;
10
11pub trait ContextServerDescriptor {
12    fn command(&self, project: Entity<Project>, cx: &AsyncApp) -> Task<Result<ServerCommand>>;
13    fn configuration(
14        &self,
15        project: Entity<Project>,
16        cx: &AsyncApp,
17    ) -> Task<Result<Option<ContextServerConfiguration>>>;
18}
19
20struct GlobalContextServerDescriptorRegistry(Entity<ContextServerDescriptorRegistry>);
21
22impl Global for GlobalContextServerDescriptorRegistry {}
23
24#[derive(Default)]
25pub struct ContextServerDescriptorRegistry {
26    context_servers: HashMap<Arc<str>, Arc<dyn ContextServerDescriptor>>,
27}
28
29impl ContextServerDescriptorRegistry {
30    /// Returns the global [`ContextServerDescriptorRegistry`].
31    pub fn global(cx: &App) -> Entity<Self> {
32        GlobalContextServerDescriptorRegistry::global(cx).0.clone()
33    }
34
35    /// Returns the global [`ContextServerDescriptorRegistry`].
36    ///
37    /// Inserts a default [`ContextServerDescriptorRegistry`] if one does not yet exist.
38    pub fn default_global(cx: &mut App) -> Entity<Self> {
39        if !cx.has_global::<GlobalContextServerDescriptorRegistry>() {
40            let registry = cx.new(|_| Self::new());
41            cx.set_global(GlobalContextServerDescriptorRegistry(registry));
42        }
43        cx.global::<GlobalContextServerDescriptorRegistry>()
44            .0
45            .clone()
46    }
47
48    pub fn new() -> Self {
49        Self {
50            context_servers: HashMap::default(),
51        }
52    }
53
54    pub fn context_server_descriptors(&self) -> Vec<(Arc<str>, Arc<dyn ContextServerDescriptor>)> {
55        self.context_servers
56            .iter()
57            .map(|(id, factory)| (id.clone(), factory.clone()))
58            .collect()
59    }
60
61    pub fn context_server_descriptor(&self, id: &str) -> Option<Arc<dyn ContextServerDescriptor>> {
62        self.context_servers.get(id).cloned()
63    }
64
65    /// Registers the provided [`ContextServerDescriptor`].
66    pub fn register_context_server_descriptor(
67        &mut self,
68        id: Arc<str>,
69        descriptor: Arc<dyn ContextServerDescriptor>,
70    ) {
71        self.context_servers.insert(id, descriptor);
72    }
73
74    /// Unregisters the [`ContextServerDescriptor`] for the server with the given ID.
75    pub fn unregister_context_server_descriptor_by_id(&mut self, server_id: &str) {
76        self.context_servers.remove(server_id);
77    }
78}