//! 宪法状态持久化模块 use crate::{ConstitutionVersion, Result, Error}; use serde::{Deserialize, Serialize}; use std::collections::HashMap; use std::path::{Path, PathBuf}; use std::fs; /// 状态快照 #[derive(Debug, Clone, Serialize, Deserialize)] pub struct StateSnapshot { /// 当前版本 pub current_version: ConstitutionVersion, /// 历史版本 pub history: Vec, /// 待处理的升级 pub pending_upgrades: HashMap, } /// 存储管理器 pub struct Storage { /// 存储路径 path: PathBuf, } impl Storage { /// 创建新的存储管理器 pub fn new(path: PathBuf) -> Self { Self { path } } /// 保存状态 pub fn save(&self, state: &StateSnapshot) -> Result<()> { // 创建目录 if let Some(parent) = self.path.parent() { fs::create_dir_all(parent) .map_err(|e| Error::StorageError(format!("创建目录失败: {}", e)))?; } // 序列化状态 let json = serde_json::to_string_pretty(state) .map_err(|e| Error::StorageError(format!("序列化失败: {}", e)))?; // 写入文件 fs::write(&self.path, json) .map_err(|e| Error::StorageError(format!("写入文件失败: {}", e)))?; Ok(()) } /// 加载状态 pub fn load(&self) -> Result { // 读取文件 let json = fs::read_to_string(&self.path) .map_err(|e| Error::StorageError(format!("读取文件失败: {}", e)))?; // 反序列化状态 let state = serde_json::from_str(&json) .map_err(|e| Error::StorageError(format!("反序列化失败: {}", e)))?; Ok(state) } /// 检查存储是否存在 pub fn exists(&self) -> bool { self.path.exists() } /// 删除存储 pub fn delete(&self) -> Result<()> { if self.exists() { fs::remove_file(&self.path) .map_err(|e| Error::StorageError(format!("删除文件失败: {}", e)))?; } Ok(()) } /// 备份状态 pub fn backup(&self, backup_path: &Path) -> Result<()> { if !self.exists() { return Err(Error::StorageError("源文件不存在".to_string())); } fs::copy(&self.path, backup_path) .map_err(|e| Error::StorageError(format!("备份失败: {}", e)))?; Ok(()) } /// 恢复状态 pub fn restore(&self, backup_path: &Path) -> Result<()> { if !backup_path.exists() { return Err(Error::StorageError("备份文件不存在".to_string())); } fs::copy(backup_path, &self.path) .map_err(|e| Error::StorageError(format!("恢复失败: {}", e)))?; Ok(()) } } #[cfg(test)] mod tests { use super::*; use nac_udm::primitives::{Hash, Address}; fn create_test_version(version: u64) -> ConstitutionVersion { ConstitutionVersion::new( version, Hash::zero(), version * 1000, 10, version * 100, Address::zero(), format!("Version {}", version), ) } fn create_test_snapshot() -> StateSnapshot { StateSnapshot { current_version: create_test_version(2), history: vec![create_test_version(1)], pending_upgrades: HashMap::new(), } } #[test] fn test_save_and_load() { let temp_dir = std::env::temp_dir(); let path = temp_dir.join("test_state.json"); let storage = Storage::new(path.clone()); let snapshot = create_test_snapshot(); assert!(storage.save(&snapshot).is_ok()); assert!(storage.exists()); let loaded = storage.load(); assert!(loaded.is_ok()); assert_eq!(loaded.expect("mainnet: handle error").current_version.version, 2); // 清理 let _ = storage.delete(); } #[test] fn test_backup_and_restore() { let temp_dir = std::env::temp_dir(); let path = temp_dir.join("test_state_backup.json"); let backup_path = temp_dir.join("test_state_backup_copy.json"); let storage = Storage::new(path.clone()); let snapshot = create_test_snapshot(); storage.save(&snapshot).expect("mainnet: handle error"); assert!(storage.backup(&backup_path).is_ok()); assert!(backup_path.exists()); storage.delete().expect("mainnet: handle error"); assert!(!storage.exists()); assert!(storage.restore(&backup_path).is_ok()); assert!(storage.exists()); // 清理 let _ = storage.delete(); let _ = fs::remove_file(backup_path); } }