wowlab_docgen_cli/context/collectors/
tidy_rules.rs1use minijinja::Value;
2use wowlab_fs::path::Path;
3use wowlab_tidy::{Config, ConfigError, ConfigRule, all_rules};
4
5use super::{ContextEntry, to_value};
6use crate::RenderCtx;
7
8#[must_use]
9pub fn collect(ctx: &RenderCtx<'_>) -> Vec<ContextEntry> {
10 match ctx.workspace.tidy_rules() {
11 Some(value) => vec![("tidy_rules", value.clone())],
12 None => Vec::new(),
13 }
14}
15
16#[must_use]
17pub fn load(root: &Path) -> Option<Value> {
18 let rules = resolved(root).ok()?;
19
20 if rules.is_empty() {
21 return None;
22 }
23
24 Some(to_value(&rules))
25}
26
27pub(crate) fn resolved(root: &Path) -> Result<Vec<ConfigRule>, ConfigError> {
28 let config_path = root.join("crates/tidy.toml");
29 let config = Config::load(&config_path)?;
30 let mut rules = config.resolved_rules(&all_rules());
31
32 rules.sort_by(|a, b| a.name.cmp(&b.name));
33
34 Ok(rules)
35}
36
37#[cfg(test)]
38mod tests {
39 use googletest::prelude::*;
40 use wowlab_tidy::ConfigRule;
41
42 #[gtest]
43 fn parse_full_config_json() -> Result<()> {
44 let json = r#"[{"name":"panic","description":"Ban panic!() in library code.","severity":"high","category":"correctness","fixable":false,"enabled":true,"ignore":["**/main.rs"]}]"#;
45 let rules: Vec<ConfigRule> = serde_json::from_str(json).or_fail()?;
46
47 verify_that!(rules, len(eq(1)))?;
48 verify_eq!(rules[0].name, "panic")?;
49 verify_eq!(rules[0].severity, "high")?;
50 verify_true!(rules[0].enabled)?;
51
52 verify_that!(rules[0].ignore, elements_are![eq("**/main.rs")])
53 }
54
55 #[gtest]
56 fn parse_with_params() -> Result<()> {
57 let json = r#"[{"name":"max_fn_lines","description":"Limit function length.","severity":"medium","category":"ast","fixable":false,"enabled":true,"params":{"threshold":150}}]"#;
58 let rules: Vec<ConfigRule> = serde_json::from_str(json).or_fail()?;
59
60 verify_eq!(rules[0].params.as_ref().or_fail()?["threshold"], 150)
61 }
62}