NAC_Blockchain/nac-constitution-clauses/src/manager/mod.rs

459 lines
13 KiB
Rust

//! 宪法条款管理器模块
//!
//! 提供条款的添加、更新、删除和版本管理功能
use crate::{ConstitutionalClause, ClauseTier};
use crate::storage::{ClauseStorage, StorageError};
use crate::validator::{ClauseValidator, ValidationError};
use nac_udm::primitives::Hash;
use serde::{Deserialize, Serialize};
use std::collections::HashMap;
use std::path::Path;
/// 管理器错误类型
#[derive(Debug)]
pub enum ManagerError {
/// 验证错误
ValidationError(ValidationError),
/// 存储错误
StorageError(StorageError),
/// 条款已存在
ClauseExists(u64),
/// 条款不存在
ClauseNotFound(u64),
/// 版本冲突
VersionConflict(u64, u32),
}
impl From<ValidationError> for ManagerError {
fn from(err: ValidationError) -> Self {
ManagerError::ValidationError(err)
}
}
impl From<StorageError> for ManagerError {
fn from(err: StorageError) -> Self {
ManagerError::StorageError(err)
}
}
/// 条款版本信息
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ClauseVersion {
/// 版本号
pub version: u32,
/// 条款内容
pub clause: ConstitutionalClause,
/// 创建时间
pub created_at: u64,
/// 创建者
pub created_by: String,
/// 变更说明
pub change_note: String,
}
/// 宪法条款管理器
pub struct ConstitutionManager {
/// 存储层
storage: ClauseStorage,
/// 验证器
validator: ClauseValidator,
/// 版本历史 (clause_index -> versions)
version_history: HashMap<u64, Vec<ClauseVersion>>,
}
impl ConstitutionManager {
/// 创建新的管理器
pub fn new<P: AsRef<Path>>(storage_path: P) -> Result<Self, ManagerError> {
let storage = ClauseStorage::new(storage_path)?;
let validator = ClauseValidator::new();
Ok(Self {
storage,
validator,
version_history: HashMap::new(),
})
}
/// 从磁盘加载管理器
pub fn load_from_disk<P: AsRef<Path>>(storage_path: P) -> Result<Self, ManagerError> {
let storage = ClauseStorage::load_from_disk(storage_path)?;
let mut validator = ClauseValidator::new();
// 注册所有已存在的条款
for clause in storage.list_all_clauses() {
validator.register_clause(clause.clause_index, vec![]);
}
Ok(Self {
storage,
validator,
version_history: HashMap::new(),
})
}
/// 添加新条款
pub fn add_clause(
&mut self,
clause: ConstitutionalClause,
created_by: String,
change_note: String,
) -> Result<(), ManagerError> {
// 检查条款是否已存在
if self.storage.load_clause(clause.clause_index).is_ok() {
return Err(ManagerError::ClauseExists(clause.clause_index));
}
// 验证条款
self.validator.validate_clause(&clause)?;
// 保存到存储
self.storage.save_clause(clause.clone())?;
// 注册到验证器
self.validator.register_clause(clause.clause_index, vec![]);
// 记录版本历史
let version = ClauseVersion {
version: 1,
clause,
created_at: Self::current_timestamp(),
created_by,
change_note,
};
self.version_history
.entry(version.clause.clause_index)
.or_insert_with(Vec::new)
.push(version);
Ok(())
}
/// 更新条款
pub fn update_clause(
&mut self,
index: u64,
new_content: String,
updated_by: String,
change_note: String,
) -> Result<(), ManagerError> {
// 加载现有条款
let old_clause = self.storage.load_clause(index)?.clone();
// 创建新版本
let mut new_clause = old_clause.clone();
new_clause.content = new_content;
new_clause.clause_hash = ClauseValidator::compute_clause_hash(&new_clause);
// 验证新条款
self.validator.validate_clause(&new_clause)?;
// 保存到存储
self.storage.save_clause(new_clause.clone())?;
// 记录版本历史
let current_version = self.version_history
.get(&index)
.and_then(|versions| versions.last())
.map(|v| v.version)
.unwrap_or(0);
let version = ClauseVersion {
version: current_version + 1,
clause: new_clause,
created_at: Self::current_timestamp(),
created_by: updated_by,
change_note,
};
self.version_history
.entry(index)
.or_insert_with(Vec::new)
.push(version);
Ok(())
}
/// 删除条款
pub fn delete_clause(&mut self, index: u64) -> Result<(), ManagerError> {
// 删除存储中的条款
self.storage.delete_clause(index)?;
// 从验证器中移除
// 注意:这里简化处理,实际应该更新依赖关系
Ok(())
}
/// 获取条款
pub fn get_clause(&self, index: u64) -> Result<&ConstitutionalClause, ManagerError> {
self.storage.load_clause(index)
.map_err(|e| ManagerError::from(e))
}
/// 获取所有条款
pub fn list_all_clauses(&self) -> Vec<&ConstitutionalClause> {
self.storage.list_all_clauses()
}
/// 按层级获取条款
pub fn list_clauses_by_tier(&self, tier: ClauseTier) -> Vec<&ConstitutionalClause> {
self.storage.list_clauses_by_tier(tier)
}
/// 获取条款版本历史
pub fn get_version_history(&self, index: u64) -> Option<&Vec<ClauseVersion>> {
self.version_history.get(&index)
}
/// 获取特定版本的条款
pub fn get_clause_version(&self, index: u64, version: u32) -> Result<&ClauseVersion, ManagerError> {
self.version_history
.get(&index)
.and_then(|versions| versions.iter().find(|v| v.version == version))
.ok_or(ManagerError::VersionConflict(index, version))
}
/// 回滚到特定版本
pub fn rollback_to_version(
&mut self,
index: u64,
version: u32,
rolled_back_by: String,
) -> Result<(), ManagerError> {
// 获取目标版本
let target_version = self.get_clause_version(index, version)?.clone();
// 创建新版本(基于目标版本的内容)
let mut new_clause = target_version.clause.clone();
new_clause.clause_hash = ClauseValidator::compute_clause_hash(&new_clause);
// 验证
self.validator.validate_clause(&new_clause)?;
// 保存
self.storage.save_clause(new_clause.clone())?;
// 记录版本历史
let current_version = self.version_history
.get(&index)
.and_then(|versions| versions.last())
.map(|v| v.version)
.unwrap_or(0);
let rollback_version = ClauseVersion {
version: current_version + 1,
clause: new_clause,
created_at: Self::current_timestamp(),
created_by: rolled_back_by,
change_note: format!("回滚到版本 {}", version),
};
self.version_history
.entry(index)
.or_insert_with(Vec::new)
.push(rollback_version);
Ok(())
}
/// 获取当前时间戳(简化实现)
fn current_timestamp() -> u64 {
use std::time::{SystemTime, UNIX_EPOCH};
SystemTime::now()
.duration_since(UNIX_EPOCH)
.unwrap()
.as_secs()
}
/// 获取条款数量统计
pub fn get_statistics(&self) -> ClauseStatistics {
ClauseStatistics {
total: self.storage.count(),
eternal: self.storage.count_by_tier(ClauseTier::Eternal),
strategic: self.storage.count_by_tier(ClauseTier::Strategic),
tactical: self.storage.count_by_tier(ClauseTier::Tactical),
}
}
}
/// 条款统计信息
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ClauseStatistics {
/// 总数
pub total: usize,
/// 永恒级数量
pub eternal: usize,
/// 战略级数量
pub strategic: usize,
/// 战术级数量
pub tactical: usize,
}
#[cfg(test)]
mod tests {
use super::*;
use tempfile::tempdir;
fn create_test_clause(index: u64, tier: ClauseTier) -> ConstitutionalClause {
let clause = ConstitutionalClause {
clause_index: index,
title: format!("测试条款 {}", index),
content: format!("这是测试条款 {} 的内容", index),
clause_hash: Hash::zero(),
effective_from: 1000,
tier,
};
let hash = ClauseValidator::compute_clause_hash(&clause);
ConstitutionalClause {
clause_hash: hash,
..clause
}
}
#[test]
fn test_add_clause() {
let dir = tempdir().unwrap();
let path = dir.path().join("clauses.json");
let mut manager = ConstitutionManager::new(&path).unwrap();
let clause = create_test_clause(1, ClauseTier::Eternal);
let result = manager.add_clause(
clause,
"测试用户".to_string(),
"初始版本".to_string(),
);
assert!(result.is_ok());
}
#[test]
fn test_update_clause() {
let dir = tempdir().unwrap();
let path = dir.path().join("clauses.json");
let mut manager = ConstitutionManager::new(&path).unwrap();
let clause = create_test_clause(1, ClauseTier::Eternal);
manager.add_clause(
clause,
"测试用户".to_string(),
"初始版本".to_string(),
).unwrap();
let result = manager.update_clause(
1,
"更新后的内容".to_string(),
"测试用户".to_string(),
"更新测试".to_string(),
);
assert!(result.is_ok());
let updated = manager.get_clause(1).unwrap();
assert_eq!(updated.content, "更新后的内容");
}
#[test]
fn test_version_history() {
let dir = tempdir().unwrap();
let path = dir.path().join("clauses.json");
let mut manager = ConstitutionManager::new(&path).unwrap();
let clause = create_test_clause(1, ClauseTier::Eternal);
manager.add_clause(
clause,
"测试用户".to_string(),
"初始版本".to_string(),
).unwrap();
manager.update_clause(
1,
"第二版内容".to_string(),
"测试用户".to_string(),
"第二版".to_string(),
).unwrap();
let history = manager.get_version_history(1).unwrap();
assert_eq!(history.len(), 2);
assert_eq!(history[0].version, 1);
assert_eq!(history[1].version, 2);
}
#[test]
fn test_rollback() {
let dir = tempdir().unwrap();
let path = dir.path().join("clauses.json");
let mut manager = ConstitutionManager::new(&path).unwrap();
let clause = create_test_clause(1, ClauseTier::Eternal);
manager.add_clause(
clause,
"测试用户".to_string(),
"初始版本".to_string(),
).unwrap();
manager.update_clause(
1,
"第二版内容".to_string(),
"测试用户".to_string(),
"第二版".to_string(),
).unwrap();
manager.rollback_to_version(
1,
1,
"测试用户".to_string(),
).unwrap();
let history = manager.get_version_history(1).unwrap();
assert_eq!(history.len(), 3);
assert_eq!(history[2].change_note, "回滚到版本 1");
}
#[test]
fn test_delete_clause() {
let dir = tempdir().unwrap();
let path = dir.path().join("clauses.json");
let mut manager = ConstitutionManager::new(&path).unwrap();
let clause = create_test_clause(1, ClauseTier::Eternal);
manager.add_clause(
clause,
"测试用户".to_string(),
"初始版本".to_string(),
).unwrap();
assert!(manager.get_clause(1).is_ok());
manager.delete_clause(1).unwrap();
assert!(manager.get_clause(1).is_err());
}
#[test]
fn test_statistics() {
let dir = tempdir().unwrap();
let path = dir.path().join("clauses.json");
let mut manager = ConstitutionManager::new(&path).unwrap();
manager.add_clause(
create_test_clause(1, ClauseTier::Eternal),
"测试用户".to_string(),
"条款1".to_string(),
).unwrap();
manager.add_clause(
create_test_clause(101, ClauseTier::Strategic),
"测试用户".to_string(),
"条款2".to_string(),
).unwrap();
let stats = manager.get_statistics();
assert_eq!(stats.total, 2);
assert_eq!(stats.eternal, 1);
assert_eq!(stats.strategic, 1);
assert_eq!(stats.tactical, 0);
}
}