1use std::path::PathBuf;
2use std::sync::Arc;
3
4use anyhow::Result;
5use async_trait::async_trait;
6use extension::{Extension, ExtensionHostProxy, ExtensionIndexedDocsProviderProxy};
7use gpui::App;
8
9use crate::{
10 IndexedDocsDatabase, IndexedDocsProvider, IndexedDocsRegistry, PackageName, ProviderId,
11};
12
13pub fn init(cx: &mut App) {
14 let proxy = ExtensionHostProxy::default_global(cx);
15 proxy.register_indexed_docs_provider_proxy(IndexedDocsRegistryProxy {
16 indexed_docs_registry: IndexedDocsRegistry::global(cx),
17 });
18}
19
20struct IndexedDocsRegistryProxy {
21 indexed_docs_registry: Arc<IndexedDocsRegistry>,
22}
23
24impl ExtensionIndexedDocsProviderProxy for IndexedDocsRegistryProxy {
25 fn register_indexed_docs_provider(&self, extension: Arc<dyn Extension>, provider_id: Arc<str>) {
26 self.indexed_docs_registry
27 .register_provider(Box::new(ExtensionIndexedDocsProvider::new(
28 extension,
29 ProviderId(provider_id),
30 )));
31 }
32
33 fn unregister_indexed_docs_provider(&self, provider_id: Arc<str>) {
34 self.indexed_docs_registry
35 .unregister_provider(&ProviderId(provider_id));
36 }
37}
38
39pub struct ExtensionIndexedDocsProvider {
40 extension: Arc<dyn Extension>,
41 id: ProviderId,
42}
43
44impl ExtensionIndexedDocsProvider {
45 pub fn new(extension: Arc<dyn Extension>, id: ProviderId) -> Self {
46 Self { extension, id }
47 }
48}
49
50#[async_trait]
51impl IndexedDocsProvider for ExtensionIndexedDocsProvider {
52 fn id(&self) -> ProviderId {
53 self.id.clone()
54 }
55
56 fn database_path(&self) -> PathBuf {
57 let mut database_path = PathBuf::from(self.extension.work_dir().as_ref());
58 database_path.push("docs");
59 database_path.push(format!("{}.0.mdb", self.id));
60
61 database_path
62 }
63
64 async fn suggest_packages(&self) -> Result<Vec<PackageName>> {
65 let packages = self
66 .extension
67 .suggest_docs_packages(self.id.0.clone())
68 .await?;
69
70 Ok(packages
71 .into_iter()
72 .map(|package| PackageName::from(package.as_str()))
73 .collect())
74 }
75
76 async fn index(&self, package: PackageName, database: Arc<IndexedDocsDatabase>) -> Result<()> {
77 self.extension
78 .index_docs(self.id.0.clone(), package.as_ref().into(), database)
79 .await
80 }
81}