//! 宪法条款验证模块 //! //! 提供条款内容验证、层级验证、依赖验证和冲突检测功能 use crate::{ConstitutionalClause, ClauseTier}; use nac_udm::primitives::Hash; use std::collections::{HashMap, HashSet}; /// 验证错误类型 #[derive(Debug, Clone, PartialEq, Eq)] pub enum ValidationError { /// 条款内容为空 EmptyContent, /// 条款标题为空 EmptyTitle, /// 无效的条款索引 InvalidIndex, /// 层级冲突 TierConflict(String), /// 依赖缺失 MissingDependency(u64), /// 循环依赖 CircularDependency(Vec), /// 条款冲突 ClauseConflict(u64, String), /// 生效时间无效 InvalidEffectiveTime, /// 哈希不匹配 HashMismatch, } /// 条款验证器 pub struct ClauseValidator { /// 已知的条款索引 known_clauses: HashSet, /// 条款依赖关系 (clause_index -> dependencies) dependencies: HashMap>, } impl ClauseValidator { /// 创建新的验证器 pub fn new() -> Self { Self { known_clauses: HashSet::new(), dependencies: HashMap::new(), } } /// 注册已知条款 pub fn register_clause(&mut self, index: u64, dependencies: Vec) { self.known_clauses.insert(index); if !dependencies.is_empty() { self.dependencies.insert(index, dependencies); } } /// 验证条款基本内容 pub fn validate_content(&self, clause: &ConstitutionalClause) -> Result<(), ValidationError> { // 验证标题 if clause.title.trim().is_empty() { return Err(ValidationError::EmptyTitle); } // 验证内容 if clause.content.trim().is_empty() { return Err(ValidationError::EmptyContent); } // 验证索引 if clause.clause_index == 0 { return Err(ValidationError::InvalidIndex); } // 验证生效时间 if clause.effective_from == 0 { return Err(ValidationError::InvalidEffectiveTime); } Ok(()) } /// 验证条款层级 pub fn validate_tier(&self, clause: &ConstitutionalClause) -> Result<(), ValidationError> { // 永恒级条款的特殊规则 if clause.tier == ClauseTier::Eternal { // 永恒级条款索引应该在1-100范围内 if clause.clause_index > 100 { return Err(ValidationError::TierConflict( "永恒级条款索引应在1-100范围内".to_string() )); } } // 战略级条款的特殊规则 if clause.tier == ClauseTier::Strategic { // 战略级条款索引应该在101-1000范围内 if clause.clause_index <= 100 || clause.clause_index > 1000 { return Err(ValidationError::TierConflict( "战略级条款索引应在101-1000范围内".to_string() )); } } // 战术级条款的特殊规则 if clause.tier == ClauseTier::Tactical { // 战术级条款索引应该大于1000 if clause.clause_index <= 1000 { return Err(ValidationError::TierConflict( "战术级条款索引应大于1000".to_string() )); } } Ok(()) } /// 验证条款依赖 pub fn validate_dependencies(&self, clause_index: u64) -> Result<(), ValidationError> { if let Some(deps) = self.dependencies.get(&clause_index) { // 检查所有依赖是否存在 for &dep in deps { if !self.known_clauses.contains(&dep) { return Err(ValidationError::MissingDependency(dep)); } } // 检查循环依赖 if let Some(cycle) = self.detect_circular_dependency(clause_index) { return Err(ValidationError::CircularDependency(cycle)); } } Ok(()) } /// 检测循环依赖 fn detect_circular_dependency(&self, start: u64) -> Option> { let mut visited = HashSet::new(); let mut path = Vec::new(); if self.dfs_cycle_detection(start, &mut visited, &mut path) { Some(path) } else { None } } /// 深度优先搜索检测循环 fn dfs_cycle_detection(&self, current: u64, visited: &mut HashSet, path: &mut Vec) -> bool { if path.contains(¤t) { path.push(current); return true; } if visited.contains(¤t) { return false; } visited.insert(current); path.push(current); if let Some(deps) = self.dependencies.get(¤t) { for &dep in deps { if self.dfs_cycle_detection(dep, visited, path) { return true; } } } path.pop(); false } /// 验证条款哈希 pub fn validate_hash(&self, clause: &ConstitutionalClause) -> Result<(), ValidationError> { let computed_hash = Self::compute_clause_hash(clause); if computed_hash != clause.clause_hash { return Err(ValidationError::HashMismatch); } Ok(()) } /// 计算条款哈希 pub fn compute_clause_hash(clause: &ConstitutionalClause) -> Hash { use sha3::{Sha3_384, Digest}; let mut hasher = Sha3_384::new(); hasher.update(clause.clause_index.to_le_bytes()); hasher.update(clause.title.as_bytes()); hasher.update(clause.content.as_bytes()); hasher.update(&[clause.tier as u8]); hasher.update(clause.effective_from.to_le_bytes()); let result = hasher.finalize(); let mut bytes = [0u8; 48]; bytes.copy_from_slice(&result); Hash::new(bytes) } /// 完整验证条款 pub fn validate_clause(&self, clause: &ConstitutionalClause) -> Result<(), ValidationError> { self.validate_content(clause)?; self.validate_tier(clause)?; self.validate_dependencies(clause.clause_index)?; self.validate_hash(clause)?; Ok(()) } } impl Default for ClauseValidator { fn default() -> Self { Self::new() } } #[cfg(test)] mod tests { use super::*; fn create_test_clause(index: u64, tier: ClauseTier) -> ConstitutionalClause { let clause = ConstitutionalClause { clause_index: index, title: "测试条款".to_string(), content: "这是一个测试条款内容".to_string(), clause_hash: Hash::zero(), effective_from: 1000, tier, }; let hash = ClauseValidator::compute_clause_hash(&clause); ConstitutionalClause { clause_hash: hash, ..clause } } #[test] fn test_validate_content() { let validator = ClauseValidator::new(); let clause = create_test_clause(1, ClauseTier::Eternal); assert!(validator.validate_content(&clause).is_ok()); } #[test] fn test_validate_empty_title() { let validator = ClauseValidator::new(); let mut clause = create_test_clause(1, ClauseTier::Eternal); clause.title = "".to_string(); assert_eq!( validator.validate_content(&clause), Err(ValidationError::EmptyTitle) ); } #[test] fn test_validate_empty_content() { let validator = ClauseValidator::new(); let mut clause = create_test_clause(1, ClauseTier::Eternal); clause.content = "".to_string(); assert_eq!( validator.validate_content(&clause), Err(ValidationError::EmptyContent) ); } #[test] fn test_validate_tier_eternal() { let validator = ClauseValidator::new(); let clause = create_test_clause(50, ClauseTier::Eternal); assert!(validator.validate_tier(&clause).is_ok()); } #[test] fn test_validate_tier_strategic() { let validator = ClauseValidator::new(); let clause = create_test_clause(500, ClauseTier::Strategic); assert!(validator.validate_tier(&clause).is_ok()); } #[test] fn test_validate_tier_tactical() { let validator = ClauseValidator::new(); let clause = create_test_clause(2000, ClauseTier::Tactical); assert!(validator.validate_tier(&clause).is_ok()); } #[test] fn test_validate_dependencies() { let mut validator = ClauseValidator::new(); validator.register_clause(1, vec![]); validator.register_clause(2, vec![1]); assert!(validator.validate_dependencies(2).is_ok()); } #[test] fn test_missing_dependency() { let mut validator = ClauseValidator::new(); validator.register_clause(2, vec![1]); assert_eq!( validator.validate_dependencies(2), Err(ValidationError::MissingDependency(1)) ); } #[test] fn test_circular_dependency() { let mut validator = ClauseValidator::new(); validator.register_clause(1, vec![2]); validator.register_clause(2, vec![1]); assert!(matches!( validator.validate_dependencies(1), Err(ValidationError::CircularDependency(_)) )); } #[test] fn test_validate_hash() { let validator = ClauseValidator::new(); let clause = create_test_clause(1, ClauseTier::Eternal); assert!(validator.validate_hash(&clause).is_ok()); } #[test] fn test_validate_hash_mismatch() { let validator = ClauseValidator::new(); let mut clause = create_test_clause(1, ClauseTier::Eternal); clause.clause_hash = Hash::zero(); assert_eq!( validator.validate_hash(&clause), Err(ValidationError::HashMismatch) ); } }