NAC_Blockchain/nac-asset-onboarding/src/state_machine.rs

190 lines
5.3 KiB
Rust

//! 资产上链状态机
use serde::{Deserialize, Serialize};
use crate::error::{OnboardingError, Result};
use chrono::{DateTime, Utc};
/// 上链状态
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
pub enum OnboardingState {
/// 待处理
Pending,
/// 合规审批中
ComplianceCheck,
/// 估值中
Valuation,
/// DNA生成中
DNAGeneration,
/// 托管中
Custody,
/// XTZH铸造中
XTZHMinting,
/// 代币发行中
TokenIssuance,
/// 区块链集成中
BlockchainIntegration,
/// 已上线
Listed,
/// 失败
Failed,
}
impl OnboardingState {
/// 获取下一个状态
pub fn next(&self) -> Result<Self> {
match self {
Self::Pending => Ok(Self::ComplianceCheck),
Self::ComplianceCheck => Ok(Self::Valuation),
Self::Valuation => Ok(Self::DNAGeneration),
Self::DNAGeneration => Ok(Self::Custody),
Self::Custody => Ok(Self::XTZHMinting),
Self::XTZHMinting => Ok(Self::TokenIssuance),
Self::TokenIssuance => Ok(Self::BlockchainIntegration),
Self::BlockchainIntegration => Ok(Self::Listed),
Self::Listed => Err(OnboardingError::StateTransitionError(
"已经是最终状态".to_string(),
)),
Self::Failed => Err(OnboardingError::StateTransitionError(
"失败状态无法继续".to_string(),
)),
}
}
/// 获取进度百分比
pub fn progress_percent(&self) -> u8 {
match self {
Self::Pending => 0,
Self::ComplianceCheck => 10,
Self::Valuation => 20,
Self::DNAGeneration => 35,
Self::Custody => 50,
Self::XTZHMinting => 65,
Self::TokenIssuance => 80,
Self::BlockchainIntegration => 90,
Self::Listed => 100,
Self::Failed => 0,
}
}
/// 转换为字符串
pub fn as_str(&self) -> &'static str {
match self {
Self::Pending => "Pending",
Self::ComplianceCheck => "ComplianceCheck",
Self::Valuation => "Valuation",
Self::DNAGeneration => "DNAGeneration",
Self::Custody => "Custody",
Self::XTZHMinting => "XTZHMinting",
Self::TokenIssuance => "TokenIssuance",
Self::BlockchainIntegration => "BlockchainIntegration",
Self::Listed => "Listed",
Self::Failed => "Failed",
}
}
}
/// 状态转换记录
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct StateTransition {
pub from_state: OnboardingState,
pub to_state: OnboardingState,
pub timestamp: DateTime<Utc>,
pub message: String,
}
/// 状态机
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct StateMachine {
current_state: OnboardingState,
transitions: Vec<StateTransition>,
}
impl StateMachine {
/// 创建新的状态机
pub fn new() -> Self {
Self {
current_state: OnboardingState::Pending,
transitions: Vec::new(),
}
}
/// 获取当前状态
pub fn current_state(&self) -> OnboardingState {
self.current_state
}
/// 转换到下一个状态
pub fn transition(&mut self, message: String) -> Result<OnboardingState> {
let next_state = self.current_state.next()?;
self.transitions.push(StateTransition {
from_state: self.current_state,
to_state: next_state,
timestamp: Utc::now(),
message,
});
self.current_state = next_state;
Ok(next_state)
}
/// 标记为失败
pub fn mark_failed(&mut self, error_message: String) {
self.transitions.push(StateTransition {
from_state: self.current_state,
to_state: OnboardingState::Failed,
timestamp: Utc::now(),
message: error_message,
});
self.current_state = OnboardingState::Failed;
}
/// 获取所有状态转换记录
pub fn get_transitions(&self) -> &[StateTransition] {
&self.transitions
}
/// 是否已完成
pub fn is_completed(&self) -> bool {
self.current_state == OnboardingState::Listed
}
/// 是否失败
pub fn is_failed(&self) -> bool {
self.current_state == OnboardingState::Failed;
}
}
impl Default for StateMachine {
fn default() -> Self {
Self::new()
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_state_progression() {
let mut sm = StateMachine::new();
assert_eq!(sm.current_state(), OnboardingState::Pending);
assert!(sm.transition("开始合规审批".to_string()).is_ok());
assert_eq!(sm.current_state(), OnboardingState::ComplianceCheck);
assert!(sm.transition("开始估值".to_string()).is_ok());
assert_eq!(sm.current_state(), OnboardingState::Valuation);
assert_eq!(sm.get_transitions().len(), 2);
}
#[test]
fn test_progress_percent() {
assert_eq!(OnboardingState::Pending.progress_percent(), 0);
assert_eq!(OnboardingState::ComplianceCheck.progress_percent(), 10);
assert_eq!(OnboardingState::Listed.progress_percent(), 100);
}
}