Skip to main content

lean_ctx/core/contextops/
sync.rs

1use std::path::Path;
2
3use serde::{Deserialize, Serialize};
4
5#[derive(Debug, Clone, Serialize, Deserialize)]
6pub struct SyncReport {
7    pub synced: Vec<String>,
8    pub skipped: Vec<String>,
9    pub errors: Vec<String>,
10}
11
12pub fn sync_all(home: &Path) -> SyncReport {
13    let inject_result = crate::rules_inject::inject_all_rules(home);
14
15    let mut synced = Vec::new();
16    synced.extend(inject_result.injected.iter().cloned());
17    synced.extend(inject_result.updated.iter().cloned());
18
19    SyncReport {
20        synced,
21        skipped: inject_result.already,
22        errors: inject_result.errors,
23    }
24}
25
26pub fn sync_agent(home: &Path, agent: &str) -> SyncReport {
27    let inject_result = crate::rules_inject::inject_rules_for_agent(home, agent);
28
29    let mut synced = Vec::new();
30    synced.extend(inject_result.injected.iter().cloned());
31    synced.extend(inject_result.updated.iter().cloned());
32
33    SyncReport {
34        synced,
35        skipped: inject_result.already,
36        errors: inject_result.errors,
37    }
38}
39
40#[cfg(test)]
41mod tests {
42    use super::*;
43
44    #[test]
45    fn sync_nonexistent_home() {
46        let home = Path::new("/tmp/nonexistent_sync_test_home");
47        let report = sync_all(home);
48        assert!(report.synced.is_empty());
49        assert!(report.errors.is_empty());
50    }
51
52    #[test]
53    fn sync_agent_unknown() {
54        let home = Path::new("/tmp/nonexistent_sync_test_home");
55        let report = sync_agent(home, "unknown_xyz");
56        assert!(report.synced.is_empty());
57        assert!(report.errors.is_empty());
58    }
59}