//! 宪法状态文件加载工具 use serde::{Deserialize, Serialize}; use std::fs; use std::path::Path; /// 宪法状态文件结构 #[derive(Debug, Clone, Serialize, Deserialize)] pub struct ConstitutionalState { pub version: String, #[serde(default)] pub timestamp: Option, #[serde(default)] pub constitutional_hash: Option, pub parameters: Vec, pub clauses: Vec, #[serde(default)] pub predicates: serde_json::Value, } /// 宪法参数 #[derive(Debug, Clone, Serialize, Deserialize)] pub struct Parameter { pub name: String, #[serde(default)] pub value: serde_json::Value, pub rust_type: String, pub clause: String, #[serde(default)] pub description: Option, } /// 宪法条款 #[derive(Debug, Clone, Serialize, Deserialize)] pub struct Clause { pub id: String, pub level: String, pub title: String, #[serde(default)] pub predicate_hash: Option, #[serde(default)] pub depends_on: Vec, } /// 加载宪法状态文件 pub fn load_constitutional_state>(path: P) -> Result { let content = fs::read_to_string(path).map_err(|e| e.to_string())?; serde_json::from_str(&content).map_err(|e| e.to_string()) } /// 查找宪法状态文件 pub fn find_constitutional_state_file>(start_dir: P) -> Option { let mut current = start_dir.as_ref().to_path_buf(); loop { let state_file = current.join("constitutional_state.json"); if state_file.exists() { return Some(state_file); } // 向上查找父目录 if !current.pop() { break; } } None } #[cfg(test)] mod tests { use super::*; use std::io::Write; use tempfile::NamedTempFile; #[test] fn test_load_constitutional_state() { let json = r#"{ "version": "1.0.0", "parameters": [ { "name": "CBPP_DT_MIN", "value": 100, "rust_type": "u64", "clause": "CONS_FLUID_BLOCK" } ], "clauses": [ { "id": "CONS_FLUID_BLOCK", "level": "eternal", "title": "流动区块生产" } ] }"#; let mut temp_file = NamedTempFile::new().unwrap(); temp_file.write_all(json.as_bytes()).unwrap(); let state = load_constitutional_state(temp_file.path()).unwrap(); assert_eq!(state.version, "1.0.0"); assert_eq!(state.parameters.len(), 1); assert_eq!(state.clauses.len(), 1); } }