NAC_Blockchain/nac-udm/src/asset_dna/asset_instance_id.rs

131 lines
3.8 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.

//! # 资产实例ID模块
//!
//! Asset Instance ID Module
use serde::{Deserialize, Serialize};
/// 资产实例IDAIID格式
#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub struct AssetInstanceID {
/// 系统代码2位
pub system_code: String,
/// 租户代码8位
pub tenant_code: String,
/// 资产类型6位
pub asset_type: String,
/// 实例序列12位
pub instance_seq: String,
/// 校验和2位
pub checksum: String,
}
impl AssetInstanceID {
/// 生成资产实例ID
pub fn generate(
system_code: &str,
tenant_code: &str,
asset_type: &str,
instance_seq: &str,
) -> Result<Self, String> {
// 验证长度
if system_code.len() != 2 {
return Err("System code must be 2 characters".to_string());
}
if tenant_code.len() != 8 {
return Err("Tenant code must be 8 characters".to_string());
}
if asset_type.len() != 6 {
return Err("Asset type must be 6 characters".to_string());
}
if instance_seq.len() != 12 {
return Err("Instance sequence must be 12 characters".to_string());
}
// 计算校验和
let checksum = Self::calculate_checksum(system_code, tenant_code, asset_type, instance_seq);
Ok(AssetInstanceID {
system_code: system_code.to_string(),
tenant_code: tenant_code.to_string(),
asset_type: asset_type.to_string(),
instance_seq: instance_seq.to_string(),
checksum,
})
}
/// 计算校验和
fn calculate_checksum(
system_code: &str,
tenant_code: &str,
asset_type: &str,
instance_seq: &str,
) -> String {
let combined = format!("{}{}{}{}", system_code, tenant_code, asset_type, instance_seq);
let sum: u32 = combined.chars().map(|c| c as u32).sum();
format!("{:02}", sum % 100)
}
/// 转换为字符串格式
pub fn to_string(&self) -> String {
format!(
"AIID-{}-{}-{}-{}-{}",
self.system_code, self.tenant_code, self.asset_type, self.instance_seq, self.checksum
)
}
/// 从字符串解析
pub fn from_string(s: &str) -> Result<Self, String> {
let parts: Vec<&str> = s.split('-').collect();
if parts.len() != 6 || parts[0] != "AIID" {
return Err("Invalid AIID format".to_string());
}
Ok(AssetInstanceID {
system_code: parts[1].to_string(),
tenant_code: parts[2].to_string(),
asset_type: parts[3].to_string(),
instance_seq: parts[4].to_string(),
checksum: parts[5].to_string(),
})
}
/// 验证校验和
pub fn verify(&self) -> bool {
let expected = Self::calculate_checksum(
&self.system_code,
&self.tenant_code,
&self.asset_type,
&self.instance_seq,
);
self.checksum == expected
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_aiid_generation() {
let aiid = AssetInstanceID::generate("GN", "CNFIN001", "010121", "2024BLDG001A")
.expect("Failed to generate AIID");
assert_eq!(aiid.system_code, "GN");
assert_eq!(aiid.tenant_code, "CNFIN001");
assert!(aiid.verify());
}
#[test]
fn test_aiid_string_conversion() {
let aiid = AssetInstanceID::generate("GN", "CNFIN001", "010121", "2024BLDG001A")
.expect("Failed to generate AIID");
let aiid_str = aiid.to_string();
let restored = AssetInstanceID::from_string(&aiid_str).expect("Failed to parse AIID");
assert_eq!(aiid.system_code, restored.system_code);
assert_eq!(aiid.tenant_code, restored.tenant_code);
assert!(restored.verify());
}
}