Skip to main content

context_core/cache/
cache.rs

1// This is intentionally thin:
2// no mutation
3// no “update” methods
4// runtime reads only
5
6use std::path::PathBuf;
7use crate::cache::CacheManifest;
8use crate::document::Document;
9use crate::types::identifiers::DocumentVersion;
10
11#[derive(Debug)]
12pub struct ContextCache {
13    pub root: PathBuf,
14    pub manifest: CacheManifest,
15}
16
17impl ContextCache {
18    pub fn load_documents(&self) -> Result<Vec<Document>, std::io::Error> {
19        let mut loaded_docs = Vec::with_capacity(self.manifest.documents.len());
20        for entry in &self.manifest.documents {
21            let path = self.root.join(&entry.file);
22            let f = std::fs::File::open(&path)?;
23            let doc: Document = serde_json::from_reader(f)
24                .map_err(|e| std::io::Error::new(std::io::ErrorKind::InvalidData, e))?;
25            
26            // Verify ID matches manifest
27            if doc.id != entry.id {
28                 return Err(std::io::Error::new(std::io::ErrorKind::InvalidData, "Document ID mismatch"));
29            }
30
31            // Verify version matches manifest (recompute from content)
32            let expected_version = DocumentVersion::from_content(doc.content.as_bytes());
33            if expected_version != entry.version {
34                return Err(std::io::Error::new(
35                    std::io::ErrorKind::InvalidData,
36                    format!(
37                        "Document version mismatch for {}: manifest says {}, content hashes to {}",
38                        entry.id.as_str(),
39                        entry.version.as_str(),
40                        expected_version.as_str(),
41                    ),
42                ));
43            }
44            loaded_docs.push(doc);
45        }
46        Ok(loaded_docs)
47    }
48}