code_baseline/rules/
mod.rs1pub mod banned_dependency;
2pub mod banned_import;
3pub mod banned_pattern;
4pub mod factory;
5pub mod file_presence;
6pub mod ratchet;
7pub mod required_pattern;
8pub mod tailwind_dark_mode;
9pub mod tailwind_theme_tokens;
10pub mod window_pattern;
11
12use crate::config::Severity;
13use std::path::{Path, PathBuf};
14
15pub trait Rule: Send + Sync {
17 fn id(&self) -> &str;
19
20 fn severity(&self) -> Severity;
22
23 fn file_glob(&self) -> Option<&str>;
25
26 fn check_file(&self, ctx: &ScanContext) -> Vec<Violation>;
28}
29
30pub struct ScanContext<'a> {
32 pub file_path: &'a Path,
33 pub content: &'a str,
34}
35
36#[derive(Debug, Clone)]
38pub struct Fix {
39 pub old: String,
40 pub new: String,
41}
42
43#[derive(Debug, Clone)]
45pub struct Violation {
46 pub rule_id: String,
47 pub severity: Severity,
48 pub file: PathBuf,
49 pub line: Option<usize>,
50 pub column: Option<usize>,
51 pub message: String,
52 pub suggest: Option<String>,
53 pub source_line: Option<String>,
54 pub fix: Option<Fix>,
55}
56
57#[derive(Debug)]
59pub enum RuleBuildError {
60 InvalidRegex(String, regex::Error),
61 MissingField(String, &'static str),
62}
63
64impl std::fmt::Display for RuleBuildError {
65 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
66 match self {
67 RuleBuildError::InvalidRegex(id, err) => {
68 write!(f, "rule '{}': invalid regex: {}", id, err)
69 }
70 RuleBuildError::MissingField(id, field) => {
71 write!(f, "rule '{}': missing required field '{}'", id, field)
72 }
73 }
74 }
75}
76
77impl std::error::Error for RuleBuildError {}