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

426 lines
12 KiB
Rust
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

//! 宪法条款生命周期管理模块
//!
//! 提供条款的激活、停用、生效时间管理和优先级管理功能
use crate::ConstitutionalClause;
use serde::{Deserialize, Serialize};
use std::collections::HashMap;
/// 条款状态
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
pub enum ClauseStatus {
/// 草稿状态
Draft,
/// 待激活
Pending,
/// 已激活
Active,
/// 已停用
Suspended,
/// 已废止
Revoked,
}
/// 条款生命周期信息
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ClauseLifecycle {
/// 条款索引
pub clause_index: u64,
/// 当前状态
pub status: ClauseStatus,
/// 优先级(数字越小优先级越高)
pub priority: u32,
/// 生效时间
pub effective_from: u64,
/// 失效时间0表示永久有效
pub effective_until: u64,
/// 激活时间
pub activated_at: Option<u64>,
/// 停用时间
pub suspended_at: Option<u64>,
/// 废止时间
pub revoked_at: Option<u64>,
/// 激活者
pub activated_by: Option<String>,
/// 停用者
pub suspended_by: Option<String>,
/// 废止者
pub revoked_by: Option<String>,
/// 停用原因
pub suspension_reason: Option<String>,
/// 废止原因
pub revocation_reason: Option<String>,
}
impl ClauseLifecycle {
/// 创建新的生命周期信息
pub fn new(clause_index: u64, effective_from: u64) -> Self {
Self {
clause_index,
status: ClauseStatus::Draft,
priority: 100, // 默认优先级
effective_from,
effective_until: 0, // 永久有效
activated_at: None,
suspended_at: None,
revoked_at: None,
activated_by: None,
suspended_by: None,
revoked_by: None,
suspension_reason: None,
revocation_reason: None,
}
}
/// 是否在指定时间生效
pub fn is_effective_at(&self, timestamp: u64) -> bool {
if self.status != ClauseStatus::Active {
return false;
}
if timestamp < self.effective_from {
return false;
}
if self.effective_until > 0 && timestamp >= self.effective_until {
return false;
}
true
}
/// 是否已激活
pub fn is_active(&self) -> bool {
self.status == ClauseStatus::Active
}
/// 是否已停用
pub fn is_suspended(&self) -> bool {
self.status == ClauseStatus::Suspended
}
/// 是否已废止
pub fn is_revoked(&self) -> bool {
self.status == ClauseStatus::Revoked
}
}
/// 生命周期管理器
pub struct LifecycleManager {
/// 条款生命周期信息
lifecycles: HashMap<u64, ClauseLifecycle>,
}
impl LifecycleManager {
/// 创建新的生命周期管理器
pub fn new() -> Self {
Self {
lifecycles: HashMap::new(),
}
}
/// 注册条款生命周期
pub fn register(&mut self, clause: &ConstitutionalClause) {
let lifecycle = ClauseLifecycle::new(clause.clause_index, clause.effective_from);
self.lifecycles.insert(clause.clause_index, lifecycle);
}
/// 激活条款
pub fn activate(
&mut self,
clause_index: u64,
activated_by: String,
timestamp: u64,
) -> Result<(), String> {
let lifecycle = self.lifecycles
.get_mut(&clause_index)
.ok_or_else(|| format!("条款 {} 不存在", clause_index))?;
if lifecycle.status == ClauseStatus::Revoked {
return Err("已废止的条款无法激活".to_string());
}
lifecycle.status = ClauseStatus::Active;
lifecycle.activated_at = Some(timestamp);
lifecycle.activated_by = Some(activated_by);
Ok(())
}
/// 停用条款
pub fn suspend(
&mut self,
clause_index: u64,
suspended_by: String,
reason: String,
timestamp: u64,
) -> Result<(), String> {
let lifecycle = self.lifecycles
.get_mut(&clause_index)
.ok_or_else(|| format!("条款 {} 不存在", clause_index))?;
if lifecycle.status == ClauseStatus::Revoked {
return Err("已废止的条款无法停用".to_string());
}
lifecycle.status = ClauseStatus::Suspended;
lifecycle.suspended_at = Some(timestamp);
lifecycle.suspended_by = Some(suspended_by);
lifecycle.suspension_reason = Some(reason);
Ok(())
}
/// 废止条款
pub fn revoke(
&mut self,
clause_index: u64,
revoked_by: String,
reason: String,
timestamp: u64,
) -> Result<(), String> {
let lifecycle = self.lifecycles
.get_mut(&clause_index)
.ok_or_else(|| format!("条款 {} 不存在", clause_index))?;
lifecycle.status = ClauseStatus::Revoked;
lifecycle.revoked_at = Some(timestamp);
lifecycle.revoked_by = Some(revoked_by);
lifecycle.revocation_reason = Some(reason);
Ok(())
}
/// 设置优先级
pub fn set_priority(&mut self, clause_index: u64, priority: u32) -> Result<(), String> {
let lifecycle = self.lifecycles
.get_mut(&clause_index)
.ok_or_else(|| format!("条款 {} 不存在", clause_index))?;
lifecycle.priority = priority;
Ok(())
}
/// 设置生效时间范围
pub fn set_effective_period(
&mut self,
clause_index: u64,
from: u64,
until: u64,
) -> Result<(), String> {
if until > 0 && from >= until {
return Err("生效时间必须早于失效时间".to_string());
}
let lifecycle = self.lifecycles
.get_mut(&clause_index)
.ok_or_else(|| format!("条款 {} 不存在", clause_index))?;
lifecycle.effective_from = from;
lifecycle.effective_until = until;
Ok(())
}
/// 获取生命周期信息
pub fn get_lifecycle(&self, clause_index: u64) -> Option<&ClauseLifecycle> {
self.lifecycles.get(&clause_index)
}
/// 获取所有激活的条款
pub fn list_active_clauses(&self) -> Vec<u64> {
self.lifecycles
.values()
.filter(|lc| lc.is_active())
.map(|lc| lc.clause_index)
.collect()
}
/// 获取在指定时间生效的条款
pub fn list_effective_clauses_at(&self, timestamp: u64) -> Vec<u64> {
self.lifecycles
.values()
.filter(|lc| lc.is_effective_at(timestamp))
.map(|lc| lc.clause_index)
.collect()
}
/// 按优先级排序的条款列表
pub fn list_clauses_by_priority(&self) -> Vec<(u64, u32)> {
let mut clauses: Vec<_> = self.lifecycles
.values()
.filter(|lc| lc.is_active())
.map(|lc| (lc.clause_index, lc.priority))
.collect();
clauses.sort_by_key(|(_, priority)| *priority);
clauses
}
/// 获取条款状态统计
pub fn get_status_statistics(&self) -> StatusStatistics {
let mut stats = StatusStatistics::default();
for lifecycle in self.lifecycles.values() {
match lifecycle.status {
ClauseStatus::Draft => stats.draft += 1,
ClauseStatus::Pending => stats.pending += 1,
ClauseStatus::Active => stats.active += 1,
ClauseStatus::Suspended => stats.suspended += 1,
ClauseStatus::Revoked => stats.revoked += 1,
}
}
stats
}
}
impl Default for LifecycleManager {
fn default() -> Self {
Self::new()
}
}
/// 状态统计信息
#[derive(Debug, Default, Clone, Serialize, Deserialize)]
pub struct StatusStatistics {
/// 草稿数量
pub draft: usize,
/// 待激活数量
pub pending: usize,
/// 已激活数量
pub active: usize,
/// 已停用数量
pub suspended: usize,
/// 已废止数量
pub revoked: usize,
}
#[cfg(test)]
mod tests {
use super::*;
use nac_udm::primitives::Hash;
use crate::ClauseTier;
fn create_test_clause(index: u64) -> ConstitutionalClause {
ConstitutionalClause {
clause_index: index,
title: "测试条款".to_string(),
content: "测试内容".to_string(),
clause_hash: Hash::zero(),
effective_from: 1000,
tier: ClauseTier::Eternal,
}
}
#[test]
fn test_register_and_activate() {
let mut manager = LifecycleManager::new();
let clause = create_test_clause(1);
manager.register(&clause);
manager.activate(1, "测试用户".to_string(), 2000).unwrap();
let lifecycle = manager.get_lifecycle(1).unwrap();
assert!(lifecycle.is_active());
assert_eq!(lifecycle.activated_by, Some("测试用户".to_string()));
}
#[test]
fn test_suspend() {
let mut manager = LifecycleManager::new();
let clause = create_test_clause(1);
manager.register(&clause);
manager.activate(1, "测试用户".to_string(), 2000).unwrap();
manager.suspend(1, "测试用户".to_string(), "测试停用".to_string(), 3000).unwrap();
let lifecycle = manager.get_lifecycle(1).unwrap();
assert!(lifecycle.is_suspended());
assert_eq!(lifecycle.suspension_reason, Some("测试停用".to_string()));
}
#[test]
fn test_revoke() {
let mut manager = LifecycleManager::new();
let clause = create_test_clause(1);
manager.register(&clause);
manager.activate(1, "测试用户".to_string(), 2000).unwrap();
manager.revoke(1, "测试用户".to_string(), "测试废止".to_string(), 4000).unwrap();
let lifecycle = manager.get_lifecycle(1).unwrap();
assert!(lifecycle.is_revoked());
assert_eq!(lifecycle.revocation_reason, Some("测试废止".to_string()));
}
#[test]
fn test_is_effective_at() {
let mut manager = LifecycleManager::new();
let clause = create_test_clause(1);
manager.register(&clause);
manager.activate(1, "测试用户".to_string(), 2000).unwrap();
manager.set_effective_period(1, 1000, 5000).unwrap();
let lifecycle = manager.get_lifecycle(1).unwrap();
assert!(!lifecycle.is_effective_at(500)); // 未生效
assert!(lifecycle.is_effective_at(3000)); // 生效中
assert!(!lifecycle.is_effective_at(6000)); // 已失效
}
#[test]
fn test_priority() {
let mut manager = LifecycleManager::new();
let clause1 = create_test_clause(1);
let clause2 = create_test_clause(2);
manager.register(&clause1);
manager.register(&clause2);
manager.activate(1, "测试用户".to_string(), 2000).unwrap();
manager.activate(2, "测试用户".to_string(), 2000).unwrap();
manager.set_priority(1, 10).unwrap();
manager.set_priority(2, 5).unwrap();
let clauses = manager.list_clauses_by_priority();
assert_eq!(clauses[0].0, 2); // 优先级5
assert_eq!(clauses[1].0, 1); // 优先级10
}
#[test]
fn test_status_statistics() {
let mut manager = LifecycleManager::new();
manager.register(&create_test_clause(1));
manager.register(&create_test_clause(2));
manager.register(&create_test_clause(3));
manager.activate(1, "测试用户".to_string(), 2000).unwrap();
manager.activate(2, "测试用户".to_string(), 2000).unwrap();
manager.suspend(2, "测试用户".to_string(), "测试".to_string(), 3000).unwrap();
let stats = manager.get_status_statistics();
assert_eq!(stats.draft, 1);
assert_eq!(stats.active, 1);
assert_eq!(stats.suspended, 1);
}
#[test]
fn test_list_active_clauses() {
let mut manager = LifecycleManager::new();
manager.register(&create_test_clause(1));
manager.register(&create_test_clause(2));
manager.register(&create_test_clause(3));
manager.activate(1, "测试用户".to_string(), 2000).unwrap();
manager.activate(2, "测试用户".to_string(), 2000).unwrap();
let active = manager.list_active_clauses();
assert_eq!(active.len(), 2);
assert!(active.contains(&1));
assert!(active.contains(&2));
}
}