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