systemprompt_loader/
extension_binary_index.rs1use std::collections::HashMap;
9use std::path::{Path, PathBuf};
10
11use systemprompt_models::DiscoveredExtension;
12
13use crate::ExtensionLoader;
14use crate::error::{ExtensionLoadError, ExtensionLoadResult};
15
16#[derive(Debug)]
17pub struct ExtensionBinaryIndex {
18 discovered: HashMap<String, DiscoveredExtension>,
19 bin_path: PathBuf,
20 is_cloud: bool,
21}
22
23impl ExtensionBinaryIndex {
24 #[must_use]
25 pub fn build(project_root: &Path, is_cloud: bool, bin_path: &str) -> Self {
26 let discovered = if is_cloud {
27 HashMap::new()
28 } else {
29 ExtensionLoader::build_binary_map(project_root)
30 };
31
32 Self {
33 discovered,
34 bin_path: PathBuf::from(bin_path),
35 is_cloud,
36 }
37 }
38
39 pub fn get_path(&self, binary_name: &str) -> ExtensionLoadResult<PathBuf> {
40 if self.is_cloud {
41 let binary_path = self.bin_path.join(binary_name);
42 return binary_path
43 .exists()
44 .then(|| self.bin_path.clone())
45 .ok_or_else(|| ExtensionLoadError::BinaryNotFound {
46 name: binary_name.to_owned(),
47 path: binary_path,
48 });
49 }
50
51 self.discovered
52 .get(binary_name)
53 .map(|ext| ext.path.clone())
54 .ok_or_else(|| ExtensionLoadError::ManifestMissing(binary_name.to_owned()))
55 }
56
57 #[must_use]
58 pub fn get_extension(&self, binary_name: &str) -> Option<&DiscoveredExtension> {
59 self.discovered.get(binary_name)
60 }
61
62 #[must_use]
63 pub fn has_extension(&self, binary_name: &str) -> bool {
64 self.bin_path.join(binary_name).exists() || self.discovered.contains_key(binary_name)
65 }
66}