registry.rs

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