difflore_core/sources/
mod.rs1use std::path::{Path, PathBuf};
4
5use chrono::{DateTime, Utc};
6
7use crate::errors::CoreError;
8
9mod claude_code_memory;
10mod simple_files;
11
12pub use claude_code_memory::ClaudeCodeMemorySource;
13pub use simple_files::{AgentsMdSource, ClaudeMdSource, CursorRulesSource};
14
15#[derive(Debug, Clone)]
16pub struct MemoryDoc {
17 pub source_id: &'static str,
18 pub path: PathBuf,
19 pub content: String,
20 pub modified_at: Option<DateTime<Utc>>,
21}
22
23pub trait Source: Send + Sync {
24 fn id(&self) -> &'static str;
25 fn label(&self) -> &'static str;
26 fn detect(&self, repo_root: &Path) -> bool;
27 fn read(&self, repo_root: &Path) -> Result<Vec<MemoryDoc>, CoreError>;
28}
29
30pub fn registered_sources() -> &'static [&'static dyn Source] {
31 static SOURCES: &[&dyn Source] = &[
32 &AgentsMdSource,
33 &ClaudeMdSource,
34 &ClaudeCodeMemorySource,
35 &CursorRulesSource,
36 ];
37 SOURCES
38}
39
40pub(crate) fn read_file_doc(
41 source_id: &'static str,
42 path: PathBuf,
43) -> Result<MemoryDoc, CoreError> {
44 let content = std::fs::read_to_string(&path)?;
45 let modified_at = std::fs::metadata(&path)
46 .and_then(|m| m.modified())
47 .ok()
48 .map(DateTime::<Utc>::from);
49 Ok(MemoryDoc {
50 source_id,
51 path,
52 content,
53 modified_at,
54 })
55}