Skip to main content

chant/repository/
spec_repository.rs

1use anyhow::Result;
2
3use crate::spec::{load_all_specs, Spec};
4
5/// A trait for loading and saving specs from a storage backend.
6pub trait SpecRepository {
7    /// Load a spec by its ID.
8    fn load(&self, id: &str) -> Result<Spec>;
9
10    /// Save a spec to storage.
11    fn save(&self, spec: &Spec) -> Result<()>;
12
13    /// List all specs from storage.
14    fn list_all(&self) -> Result<Vec<Spec>>;
15}
16
17/// File-based implementation of SpecRepository.
18pub struct FileSpecRepository {
19    specs_dir: std::path::PathBuf,
20}
21
22impl FileSpecRepository {
23    /// Create a new FileSpecRepository for the given specs directory.
24    pub fn new(specs_dir: std::path::PathBuf) -> Self {
25        Self { specs_dir }
26    }
27
28    /// Get the specs directory path.
29    pub fn specs_dir(&self) -> &std::path::Path {
30        &self.specs_dir
31    }
32}
33
34impl SpecRepository for FileSpecRepository {
35    fn load(&self, id: &str) -> Result<Spec> {
36        let spec_path = self.specs_dir.join(format!("{}.md", id));
37        Spec::load(&spec_path)
38    }
39
40    fn save(&self, spec: &Spec) -> Result<()> {
41        let spec_path = self.specs_dir.join(format!("{}.md", spec.id));
42        spec.save(&spec_path)
43    }
44
45    fn list_all(&self) -> Result<Vec<Spec>> {
46        load_all_specs(&self.specs_dir)
47    }
48}