wowlab_tidy/languages/rust/rules/style/
long_compound_name.rs1use ra_ap_syntax::ast;
2
3use super::naming;
4use crate::{AstCtx, Example, Violation};
5
6#[rustfmt::skip]
7const EXAMPLES: &[Example] = &[
8 Example {
9 label: "five-word struct name",
10 code: "struct GlobalApplicationConfigManagerImpl;",
11 pass: false,
12 },
13 Example {
14 label: "five-word enum name",
15 code: "enum BookingRequestQueueItemState { A }",
16 pass: false,
17 },
18 Example {
19 label: "five-word trait name",
20 code: "trait AsyncRemoteAccountDataSource {}",
21 pass: false,
22 },
23 Example {
24 label: "five-word type alias",
25 code: "type SharedRemoteAccountDataCache = ();",
26 pass: false,
27 },
28 Example {
29 label: "two-word name",
30 code: "struct AppConfig;",
31 pass: true,
32 },
33 Example {
34 label: "four words is at the threshold",
35 code: "struct HtmlParserConfigBuilder;",
36 pass: true,
37 },
38 Example {
39 label: "acronym run counts as one word",
40 code: "struct HTMLParserConfigBuilder;",
41 pass: true,
42 },
43 Example {
44 label: "long name in test module",
45 code: "#[cfg(test)]\nmod tests {\n struct GlobalApplicationConfigManagerFake;\n}",
46 pass: true,
47 },
48];
49
50crate::ast_rule!(
51 long_compound_name,
52 "Flag type definitions whose CamelCase name compounds more than threshold words.",
53 "Rust item names are short: `AppConfig` over `GlobalApplicationConfig`; long compounds hide the item's essence (M-SHORT-NAMES).",
54 Low,
55 params { threshold: i64 = 4 },
56);
57
58fn check_long_compound_name(ctx: &AstCtx<'_>) -> Vec<Violation> {
59 let threshold = ctx
60 .file
61 .config
62 .get_usize("rust_long_compound_name", &PARAMS[0]);
63
64 ctx.nodes::<ast::Item>()
65 .filter(|item| !ctx.is_in_test(item))
66 .filter_map(|item| {
67 let name = naming::type_def_name(&item)?;
68 let name_text = name.text();
69 let words = naming::segments(&name_text).len();
70
71 (words > threshold).then(|| {
72 ctx.violation(
73 &name,
74 format!(
75 "type name `{name_text}` compounds {words} words (max {threshold}) — shorten it"
76 ),
77 )
78 })
79 })
80 .collect()
81}
82
83crate::tidy_ast_test!(check_long_compound_name, {
84 crate::example_tests!(EXAMPLES, check_long_compound_name);
85});