wowlab_tidy/languages/rust/rules/hygiene/
imperative_talent_wiring.rs1use crate::{Example, FileCtx, Violation, violation};
2
3#[rustfmt::skip]
4const EXAMPLES: &[Example] = &[
5 Example {
6 label: "imperative talent branch",
7 code: "if params.talent_picked(TALENT::TEST) { wire(); }",
8 pass: false,
9 },
10 Example {
11 label: "coupled imperative talent branch",
12 code: "if enabled && params.talent_ranked_or_specialization(TALENT::TEST) { wire(); }",
13 pass: false,
14 },
15 Example {
16 label: "declarative config gate",
17 code: "gate: params.talent_picked(TALENT::TEST),",
18 pass: true,
19 },
20];
21
22crate::line_rule!(
23 imperative_talent_wiring,
24 "Require talent-gated config wiring to use declarative config rows.",
25 "Direct talent branches in config modules recreate registration walls; use define_spec_config field, aura, or wiring rows and reserve finish blocks for coupled runtime work.",
26 Medium,
27);
28
29fn check_imperative_talent_wiring(ctx: &FileCtx<'_>) -> Vec<Violation> {
30 let is_config =
31 ctx.rel.starts_with("crates/engine-content/src/hooks/") && ctx.rel.ends_with("/config.rs");
32
33 if !is_config && !cfg!(test) {
34 return Vec::new();
35 }
36
37 ctx.lines
38 .iter()
39 .enumerate()
40 .filter(|(_, line)| {
41 let line = line.trim();
42
43 line.starts_with("if ") && line.contains("params.talent_")
44 })
45 .map(|(index, _)| {
46 violation(
47 ctx.rel,
48 index + 1,
49 "imperative talent-gated config branch — use a declarative config row",
50 )
51 })
52 .collect()
53}
54
55crate::tidy_test!(check_imperative_talent_wiring, {
56 crate::example_tests!(EXAMPLES, check_imperative_talent_wiring);
57});