dfx_core/extension/manager/
list.rs1use super::ExtensionManager;
2use crate::error::extension::{ListAvailableExtensionsError, ListInstalledExtensionsError};
3use crate::extension::ExtensionName;
4use crate::extension::catalog::ExtensionCatalog;
5use crate::extension::installed::InstalledExtensionList;
6use std::vec;
7use url::Url;
8
9pub type AvailableExtensionList = Vec<ExtensionName>;
10
11impl ExtensionManager {
12 pub fn list_installed_extensions(
13 &self,
14 ) -> Result<InstalledExtensionList, ListInstalledExtensionsError> {
15 if !self.dir.exists() {
16 return Ok(vec![]);
17 }
18 let dir_content = crate::fs::read_dir(&self.dir)?;
19
20 let extensions = dir_content
21 .filter_map(|v| {
22 let dir_entry = v.ok()?;
23 if dir_entry.file_type().is_ok_and(|e| e.is_dir())
24 && !dir_entry.file_name().to_str()?.starts_with(".tmp")
25 {
26 let name = dir_entry.file_name().to_string_lossy().to_string();
27 Some(name)
28 } else {
29 None
30 }
31 })
32 .collect();
33 Ok(extensions)
34 }
35
36 pub async fn list_available_extensions(
37 &self,
38 catalog_url: Option<&Url>,
39 ) -> Result<AvailableExtensionList, ListAvailableExtensionsError> {
40 let catalog = ExtensionCatalog::fetch(catalog_url)
41 .await
42 .map_err(ListAvailableExtensionsError::FetchCatalog)?;
43 let extensions: Vec<String> = catalog.0.into_keys().collect();
44
45 Ok(extensions)
46 }
47}