registry.rs

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