84 lines
2.5 KiB
Rust
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);
|
|
}
|
|
}
|