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}