lean_ctx/core/property_graph/
meta.rs1use serde::{Deserialize, Serialize};
2use std::path::PathBuf;
3
4#[derive(Debug, Clone, Serialize, Deserialize)]
5#[serde(default)]
6pub struct PropertyGraphMetaV1 {
7 pub schema_version: u32,
8 pub engine_version: u32,
15 pub built_with: String,
18 pub project_root: String,
23 pub built_at: String,
25 pub git_head: Option<String>,
27 pub git_dirty: Option<bool>,
29 pub nodes: Option<usize>,
31 pub edges: Option<usize>,
33 pub files_indexed: Option<usize>,
35 pub build_time_ms: Option<u64>,
37}
38
39impl Default for PropertyGraphMetaV1 {
40 fn default() -> Self {
41 Self {
42 schema_version: 1,
43 engine_version: 0,
44 built_with: String::new(),
45 project_root: String::new(),
46 built_at: String::new(),
47 git_head: None,
48 git_dirty: None,
49 nodes: None,
50 edges: None,
51 files_indexed: None,
52 build_time_ms: None,
53 }
54 }
55}
56
57pub fn meta_path(project_root: &str) -> PathBuf {
58 super::graph_dir(project_root).join("graph.meta.json")
59}
60
61pub fn load_meta(project_root: &str) -> Option<PropertyGraphMetaV1> {
62 let path = meta_path(project_root);
63 let s = std::fs::read_to_string(path).ok()?;
64 let meta: PropertyGraphMetaV1 = serde_json::from_str(&s).ok()?;
65 if meta.schema_version != 1 || meta.built_at.trim().is_empty() {
66 return None;
67 }
68 Some(meta)
69}
70
71pub fn write_meta(project_root: &str, meta: &PropertyGraphMetaV1) -> Result<PathBuf, String> {
72 let path = meta_path(project_root);
73 if let Some(parent) = path.parent() {
74 std::fs::create_dir_all(parent).map_err(|e| e.to_string())?;
75 }
76 let json = serde_json::to_string_pretty(meta).map_err(|e| e.to_string())?;
77 crate::config_io::write_atomic(&path, &json)?;
78 Ok(path)
79}