Skip to main content

mdvault_core/captures/
repository.rs

1use std::fs;
2use std::path::{Path, PathBuf};
3
4use super::discovery::discover_captures;
5use super::lua_loader::load_capture_from_lua;
6use super::types::{
7    CaptureDiscoveryError, CaptureFormat, CaptureInfo, CaptureRepoError, CaptureSpec,
8    LoadedCapture,
9};
10
11/// Repository for discovering and loading capture specifications
12pub struct CaptureRepository {
13    pub root: PathBuf,
14    pub captures: Vec<CaptureInfo>,
15}
16
17impl CaptureRepository {
18    /// Create a new repository by scanning the captures directory
19    pub fn new(root: &Path) -> Result<Self, CaptureDiscoveryError> {
20        let captures = discover_captures(root)?;
21        Ok(Self { root: root.to_path_buf(), captures })
22    }
23
24    /// List all discovered captures
25    pub fn list_all(&self) -> &[CaptureInfo] {
26        &self.captures
27    }
28
29    /// Load a capture by its logical name
30    pub fn get_by_name(&self, name: &str) -> Result<LoadedCapture, CaptureRepoError> {
31        let info = self
32            .captures
33            .iter()
34            .find(|c| c.logical_name == name)
35            .ok_or_else(|| CaptureRepoError::NotFound(name.to_string()))?;
36
37        let spec = match info.format {
38            CaptureFormat::Lua => load_capture_from_lua(&info.path)?,
39            CaptureFormat::Yaml => {
40                // Emit deprecation warning for YAML captures
41                eprintln!(
42                    "warning: YAML captures are deprecated. Please migrate '{}' to Lua format.",
43                    info.path.display()
44                );
45
46                let content = fs::read_to_string(&info.path).map_err(|e| {
47                    CaptureRepoError::Io { path: info.path.clone(), source: e }
48                })?;
49
50                serde_yaml::from_str::<CaptureSpec>(&content).map_err(|e| {
51                    CaptureRepoError::Parse { path: info.path.clone(), source: e }
52                })?
53            }
54        };
55
56        Ok(LoadedCapture {
57            logical_name: info.logical_name.clone(),
58            path: info.path.clone(),
59            spec,
60        })
61    }
62}