mdvault_core/captures/
repository.rs

1use std::fs;
2use std::path::{Path, PathBuf};
3
4use super::discovery::discover_captures;
5use super::types::{
6    CaptureDiscoveryError, CaptureInfo, CaptureRepoError, CaptureSpec, LoadedCapture,
7};
8
9/// Repository for discovering and loading capture specifications
10pub struct CaptureRepository {
11    pub root: PathBuf,
12    pub captures: Vec<CaptureInfo>,
13}
14
15impl CaptureRepository {
16    /// Create a new repository by scanning the captures directory
17    pub fn new(root: &Path) -> Result<Self, CaptureDiscoveryError> {
18        let captures = discover_captures(root)?;
19        Ok(Self { root: root.to_path_buf(), captures })
20    }
21
22    /// List all discovered captures
23    pub fn list_all(&self) -> &[CaptureInfo] {
24        &self.captures
25    }
26
27    /// Load a capture by its logical name
28    pub fn get_by_name(&self, name: &str) -> Result<LoadedCapture, CaptureRepoError> {
29        let info = self
30            .captures
31            .iter()
32            .find(|c| c.logical_name == name)
33            .ok_or_else(|| CaptureRepoError::NotFound(name.to_string()))?;
34
35        let content = fs::read_to_string(&info.path)
36            .map_err(|e| CaptureRepoError::Io { path: info.path.clone(), source: e })?;
37
38        let spec: CaptureSpec = serde_yaml::from_str(&content).map_err(|e| {
39            CaptureRepoError::Parse { path: info.path.clone(), source: e }
40        })?;
41
42        Ok(LoadedCapture {
43            logical_name: info.logical_name.clone(),
44            path: info.path.clone(),
45            spec,
46        })
47    }
48}