1use collections::{HashMap, HashSet};
2use gpui::{App, Global, SharedString};
3use parking_lot::RwLock;
4use std::{ops::Deref, sync::Arc};
5
6use language::{ManifestName, ManifestProvider};
7
8#[derive(Default)]
9struct ManifestProvidersState {
10 providers: HashMap<ManifestName, Arc<dyn ManifestProvider>>,
11}
12
13#[derive(Clone, Default)]
14pub struct ManifestProvidersStore(Arc<RwLock<ManifestProvidersState>>);
15
16#[derive(Default)]
17struct GlobalManifestProvider(ManifestProvidersStore);
18
19impl Deref for GlobalManifestProvider {
20 type Target = ManifestProvidersStore;
21
22 fn deref(&self) -> &Self::Target {
23 &self.0
24 }
25}
26
27impl Global for GlobalManifestProvider {}
28
29impl ManifestProvidersStore {
30 /// Returns the global [`ManifestStore`].
31 ///
32 /// Inserts a default [`ManifestStore`] if one does not yet exist.
33 pub fn global(cx: &mut App) -> Self {
34 cx.default_global::<GlobalManifestProvider>().0.clone()
35 }
36
37 pub fn register(&self, provider: Arc<dyn ManifestProvider>) {
38 self.0.write().providers.insert(provider.name(), provider);
39 }
40
41 pub fn unregister(&self, name: &SharedString) {
42 self.0.write().providers.remove(name);
43 }
44
45 pub(super) fn get(&self, name: &SharedString) -> Option<Arc<dyn ManifestProvider>> {
46 self.0.read().providers.get(name).cloned()
47 }
48 pub(crate) fn manifest_file_names(&self) -> HashSet<ManifestName> {
49 self.0.read().providers.keys().cloned().collect()
50 }
51}