NAC_Blockchain/cargo-constitution/src/lib.rs

84 lines
2.5 KiB
Rust

//! cargo-constitution: Rust编译器Lint插件
//!
//! 在编译期验证Rust代码是否符合NAC宪法约束
pub mod lints;
pub mod utils;
pub use lints::{LintRunner, LintViolation, Severity, ConstitutionalParameter, Obligation};
pub use utils::{load_constitutional_state, find_constitutional_state_file};
use std::path::Path;
use walkdir::WalkDir;
/// 检查项目中的所有Rust文件
pub fn check_project<P: AsRef<Path>>(project_dir: P) -> Result<Vec<LintViolation>, String> {
// 1. 查找宪法状态文件
let state_file = find_constitutional_state_file(&project_dir)
.ok_or("Constitutional state file not found")?;
// 2. 加载宪法状态
let state = load_constitutional_state(&state_file)?;
// 3. 转换参数格式
let parameters: Vec<ConstitutionalParameter> = state
.parameters
.iter()
.map(|p| ConstitutionalParameter {
name: p.name.clone(),
value: p.value.to_string().trim_matches('"').to_string(),
rust_type: p.rust_type.clone(),
clause: p.clause.clone(),
})
.collect();
// 4. 提取条款列表
let clauses: Vec<String> = state.clauses.iter().map(|c| c.id.clone()).collect();
// 5. 提取义务列表(简化处理)
let obligations: Vec<Obligation> = vec![];
// 6. 创建lint运行器
let runner = LintRunner::new(parameters, clauses, obligations);
// 7. 遍历所有Rust文件
let mut all_violations = Vec::new();
for entry in WalkDir::new(&project_dir)
.into_iter()
.filter_map(|e| e.ok())
.filter(|e| e.path().extension().map_or(false, |ext| ext == "rs"))
{
let path = entry.path();
if let Ok(source) = std::fs::read_to_string(path) {
let violations = runner.run(&source, path.to_str().expect("mainnet: handle error"));
all_violations.extend(violations);
}
}
Ok(all_violations)
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_lint_runner() {
let params = vec![ConstitutionalParameter {
name: "TEST_PARAM".to_string(),
value: "42".to_string(),
rust_type: "u64".to_string(),
clause: "TEST_CLAUSE".to_string(),
}];
let clauses = vec!["TEST_CLAUSE".to_string()];
let obligations = vec![];
let runner = LintRunner::new(params, clauses, obligations);
let source = "let x = 42;";
let violations = runner.run(source, "test.rs");
assert_eq!(violations.len(), 1);
}
}