garbage_code_hunter/rules/
mod.rs1use std::path::Path;
2use syn::File;
3
4use crate::analyzer::CodeIssue;
5
6pub mod advanced_rust;
7pub mod complexity;
8pub mod comprehensive_rust;
9pub mod duplication;
10pub mod naming;
11pub mod rust_specific;
12
13pub trait Rule {
14 #[allow(dead_code)]
15 fn name(&self) -> &'static str;
16 fn check(
17 &self,
18 file_path: &Path,
19 syntax_tree: &File,
20 content: &str,
21 lang: &str,
22 ) -> Vec<CodeIssue>;
23}
24
25pub struct RuleEngine {
26 rules: Vec<Box<dyn Rule>>,
27}
28
29impl RuleEngine {
30 pub fn new() -> Self {
31 let mut rules: Vec<Box<dyn Rule>> = Vec::new();
32
33 rules.push(Box::new(naming::TerribleNamingRule));
35 rules.push(Box::new(naming::SingleLetterVariableRule));
36 rules.push(Box::new(complexity::DeepNestingRule));
37 rules.push(Box::new(complexity::LongFunctionRule));
38 rules.push(Box::new(duplication::CodeDuplicationRule));
39 rules.push(Box::new(rust_specific::UnwrapAbuseRule));
40 rules.push(Box::new(rust_specific::UnnecessaryCloneRule));
41
42 rules.push(Box::new(advanced_rust::ComplexClosureRule));
44 rules.push(Box::new(advanced_rust::LifetimeAbuseRule));
45 rules.push(Box::new(advanced_rust::TraitComplexityRule));
46 rules.push(Box::new(advanced_rust::GenericAbuseRule));
47
48 rules.push(Box::new(comprehensive_rust::ChannelAbuseRule));
50 rules.push(Box::new(comprehensive_rust::AsyncAbuseRule));
51 rules.push(Box::new(comprehensive_rust::DynTraitAbuseRule));
52 rules.push(Box::new(comprehensive_rust::UnsafeAbuseRule));
53 rules.push(Box::new(comprehensive_rust::FFIAbuseRule));
54 rules.push(Box::new(comprehensive_rust::MacroAbuseRule));
55 rules.push(Box::new(comprehensive_rust::ModuleComplexityRule));
56 rules.push(Box::new(comprehensive_rust::PatternMatchingAbuseRule));
57 rules.push(Box::new(comprehensive_rust::ReferenceAbuseRule));
58 rules.push(Box::new(comprehensive_rust::BoxAbuseRule));
59 rules.push(Box::new(comprehensive_rust::SliceAbuseRule));
60
61 Self { rules }
62 }
63
64 pub fn check_file(
65 &self,
66 file_path: &Path,
67 syntax_tree: &File,
68 content: &str,
69 lang: &str,
70 ) -> Vec<CodeIssue> {
71 let mut issues = Vec::new();
72
73 for rule in &self.rules {
74 issues.extend(rule.check(file_path, syntax_tree, content, lang));
75 }
76
77 issues
78 }
79}