Skip to main content

dfx_core/extension/manager/
list.rs

1use 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}