harper_core/linting/
chock_full.rs1use crate::{
2 Token, TokenStringExt,
3 patterns::{EitherPattern, Pattern, SequencePattern, WhitespacePattern, WordSet},
4};
5
6use super::{Lint, LintKind, PatternLinter, Suggestion};
7
8pub struct ChockFull {
9 pattern: Box<dyn Pattern>,
10}
11
12impl Default for ChockFull {
13 fn default() -> Self {
14 Self {
15 pattern: Box::new(
16 SequencePattern::default()
17 .then(WordSet::new(&["chalk", "choke"]))
18 .then(EitherPattern::new(vec![
19 Box::new(WhitespacePattern),
20 Box::new(|tok: &Token, _source: &[char]| tok.kind.is_hyphen()),
21 ]))
22 .then_exact_word("full"),
23 ),
24 }
25 }
26}
27
28impl PatternLinter for ChockFull {
29 fn pattern(&self) -> &dyn Pattern {
30 self.pattern.as_ref()
31 }
32
33 fn match_to_lint(&self, matched_toks: &[Token], source: &[char]) -> Option<Lint> {
34 let span = matched_toks.span()?;
35
36 Some(Lint {
37 span,
38 lint_kind: LintKind::WordChoice,
39 suggestions: vec![Suggestion::replace_with_match_case_str(
40 "chock-full",
41 span.get_content(source),
42 )],
43 message: format!(
44 "The standard term is \"chock-full\"{}.",
45 if matched_toks[1].kind.is_whitespace() {
46 ", and it should be hyphenated"
47 } else {
48 ""
49 }
50 ),
51 priority: 126,
52 })
53 }
54
55 fn description(&self) -> &'static str {
56 "Flags common soundalikes of \"chock-full\" and makes sure they're hyphenated."
57 }
58}
59
60#[cfg(test)]
61mod tests {
62 use super::ChockFull;
63 use crate::linting::tests::{assert_lint_count, assert_suggestion_result};
64
65 #[test]
66 fn allows_correct_form() {
67 assert_lint_count(
68 "'Chalk full', 'chalk-full', 'choke full', and 'choke-full' are nonstandard forms of 'chock-full'.",
69 ChockFull::default(),
70 4,
71 );
72 }
73
74 #[test]
75 fn lower_space_chalk() {
76 assert_suggestion_result(
77 "The codebase is chalk full of errors that we need to address.",
78 ChockFull::default(),
79 "The codebase is chock-full of errors that we need to address.",
80 );
81 }
82
83 #[test]
84 fn lower_space_choke() {
85 assert_suggestion_result(
86 "The project is choke full of questionable decisions that we need to revisit.",
87 ChockFull::default(),
88 "The project is chock-full of questionable decisions that we need to revisit.",
89 );
90 }
91
92 #[test]
93 fn upper_space_chalk() {
94 assert_suggestion_result(
95 "Chalk full of deprecated methods; we should refactor.",
96 ChockFull::default(),
97 "Chock-full of deprecated methods; we should refactor.",
98 );
99 }
100
101 #[test]
102 fn upper_space_choke() {
103 assert_suggestion_result(
104 "Choke full of unnecessary complexity; simplify it.",
105 ChockFull::default(),
106 "Chock-full of unnecessary complexity; simplify it.",
107 );
108 }
109
110 #[test]
111 fn lower_hyphen_chalk() {
112 assert_suggestion_result(
113 "The code is chalk-full of bugs; we need to debug before release.",
114 ChockFull::default(),
115 "The code is chock-full of bugs; we need to debug before release.",
116 );
117 }
118
119 #[test]
120 fn lower_hyphen_choke() {
121 assert_suggestion_result(
122 "The project is choke-full of warnings; we should address them.",
123 ChockFull::default(),
124 "The project is chock-full of warnings; we should address them.",
125 );
126 }
127
128 #[test]
129 fn upper_hyphen_chalk() {
130 assert_suggestion_result(
131 "Chalk-full of features, but we only need a few.",
132 ChockFull::default(),
133 "Chock-full of features, but we only need a few.",
134 );
135 }
136
137 #[test]
138 fn upper_hyphen_choke() {
139 assert_suggestion_result(
140 "Choke-full of pitfalls; let's consider alternatives.",
141 ChockFull::default(),
142 "Chock-full of pitfalls; let's consider alternatives.",
143 );
144 }
145}