1pub mod avoid_mutable_accumulation;
3pub mod brace_spacing;
4pub mod completion_function_naming;
5pub mod consistent_error_handling;
6pub mod descriptive_error_messages;
7pub mod discourage_bare_ignore;
8pub mod discourage_underscore_commands;
9pub mod exported_function_docs;
10pub mod kebab_case_commands;
11pub mod max_positional_params;
12pub mod missing_command_docs;
13pub mod missing_type_annotation;
14pub mod pipe_spacing;
15pub mod prefer_builtin_commands;
16pub mod prefer_builtin_system_commands;
17pub mod prefer_builtin_text_transforms;
18pub mod prefer_compound_assignment;
19pub mod prefer_each_over_for;
20pub mod prefer_error_make;
21pub mod prefer_is_not_empty;
22pub mod prefer_lines_over_split;
23pub mod prefer_match_over_if_chain;
24pub mod prefer_parse_command;
25pub mod prefer_parse_over_each_split;
26pub mod prefer_range_iteration;
27pub mod prefer_where_over_each_if;
28pub mod screaming_snake_constants;
29pub mod snake_case_variables;
30pub mod unnecessary_mut;
31pub mod unnecessary_variable_before_return;
32
33use std::collections::HashMap;
34
35use crate::rule::{Rule, RuleMetadata};
36
37pub struct RuleRegistry {
38 rules: HashMap<String, Rule>,
39}
40
41impl RuleRegistry {
42 #[must_use]
43 pub fn new() -> Self {
44 Self {
45 rules: HashMap::new(),
46 }
47 }
48
49 pub fn register(&mut self, rule: Rule) {
50 let id = rule.id().to_string();
51 self.rules.insert(id, rule);
52 }
53
54 #[must_use]
55 pub fn get_rule(&self, id: &str) -> Option<&Rule> {
56 self.rules.get(id)
57 }
58
59 pub fn all_rules(&self) -> impl Iterator<Item = &Rule> {
60 self.rules.values()
61 }
62
63 #[must_use]
64 pub fn with_default_rules() -> Self {
65 let mut registry = Self::new();
66
67 registry.register(Rule::Regex(
69 Box::<snake_case_variables::SnakeCaseVariables>::default(),
70 ));
71 registry.register(Rule::Regex(
72 Box::<kebab_case_commands::KebabCaseCommands>::default(),
73 ));
74 registry.register(Rule::Regex(Box::<
75 screaming_snake_constants::ScreamingSnakeConstants,
76 >::default()));
77 registry.register(Rule::Regex(Box::new(brace_spacing::BraceSpacing)));
78 registry.register(Rule::Regex(Box::new(
79 unnecessary_variable_before_return::UnnecessaryVariableBeforeReturn::new(),
80 )));
81 registry.register(Rule::Regex(Box::new(prefer_is_not_empty::PreferIsNotEmpty)));
82 registry.register(Rule::Regex(Box::new(
83 discourage_bare_ignore::DiscouragedBareIgnore::new(),
84 )));
85 registry.register(Rule::Regex(Box::new(
86 discourage_underscore_commands::DiscourageUnderscoreCommands::new(),
87 )));
88 registry.register(Rule::Regex(Box::new(
89 completion_function_naming::CompletionFunctionNaming::new(),
90 )));
91
92 registry.register(Rule::Ast(Box::<pipe_spacing::PipeSpacing>::default()));
94 registry.register(Rule::Ast(Box::<
95 prefer_compound_assignment::PreferCompoundAssignment,
96 >::default()));
97 registry.register(Rule::Ast(Box::new(unnecessary_mut::UnnecessaryMut::new())));
98
99 registry.register(Rule::Regex(Box::new(
101 prefer_error_make::PreferErrorMake::new(),
102 )));
103 registry.register(Rule::Regex(Box::new(
104 avoid_mutable_accumulation::AvoidMutableAccumulation,
105 )));
106 registry.register(Rule::Regex(Box::new(
107 prefer_range_iteration::PreferRangeIteration::new(),
108 )));
109 registry.register(Rule::Regex(Box::new(
110 prefer_parse_command::PreferParseCommand::new(),
111 )));
112 registry.register(Rule::Regex(Box::new(
113 consistent_error_handling::ConsistentErrorHandling::new(),
114 )));
115 registry.register(Rule::Regex(Box::new(
116 prefer_match_over_if_chain::PreferMatchOverIfChain::new(),
117 )));
118 registry.register(Rule::Regex(Box::new(
119 prefer_each_over_for::PreferEachOverFor::new(),
120 )));
121 registry.register(Rule::Regex(Box::new(
122 descriptive_error_messages::DescriptiveErrorMessages::new(),
123 )));
124 registry.register(Rule::Regex(Box::new(
125 prefer_builtin_commands::PreferBuiltinForCommonCommands::new(),
126 )));
127 registry.register(Rule::Regex(Box::new(
128 prefer_builtin_text_transforms::PreferBuiltinTextTransforms::new(),
129 )));
130 registry.register(Rule::Regex(Box::new(
131 prefer_builtin_system_commands::PreferBuiltinSystemCommands::new(),
132 )));
133
134 registry.register(Rule::Regex(Box::new(
136 prefer_where_over_each_if::PreferWhereOverEachIf,
137 )));
138 registry.register(Rule::Regex(Box::new(
139 prefer_lines_over_split::PreferLinesOverSplit::new(),
140 )));
141
142 registry.register(Rule::Ast(Box::new(
144 prefer_parse_over_each_split::PreferParseOverEachSplit,
145 )));
146
147 registry.register(Rule::Regex(Box::new(
149 missing_command_docs::MissingCommandDocs::new(),
150 )));
151 registry.register(Rule::Regex(Box::new(
152 exported_function_docs::ExportedFunctionDocs,
153 )));
154
155 registry.register(Rule::Ast(Box::new(
157 missing_type_annotation::MissingTypeAnnotation::new(),
158 )));
159
160 registry
161 }
162}
163
164impl Default for RuleRegistry {
165 fn default() -> Self {
166 Self::new()
167 }
168}