harper_core/linting/
hedging.rs1use crate::linting::{Lint, LintKind, PatternLinter};
2use crate::patterns::{EitherPattern, ExactPhrase, Pattern};
3use crate::{Token, TokenStringExt};
4
5pub struct Hedging {
7 pattern: Box<dyn Pattern>,
8}
9
10impl Default for Hedging {
11 fn default() -> Self {
12 let phrases = vec!["I would argue that", ", so to speak", "to a certain degree"];
13
14 let patterns: Vec<Box<dyn Pattern>> = phrases
15 .into_iter()
16 .map(|s| Box::new(ExactPhrase::from_phrase(s)) as Box<dyn Pattern>)
17 .collect();
18
19 let pattern = Box::new(EitherPattern::new(patterns));
20 Self { pattern }
21 }
22}
23
24impl PatternLinter for Hedging {
25 fn pattern(&self) -> &dyn Pattern {
26 self.pattern.as_ref()
27 }
28
29 fn match_to_lint(&self, matched_tokens: &[Token], _source: &[char]) -> Option<Lint> {
30 let span = matched_tokens.span()?;
31 Some(Lint {
32 span,
33 lint_kind: LintKind::Miscellaneous,
34 suggestions: Vec::new(),
35 message: "You're hedging.".to_string(),
36 priority: 31,
37 })
38 }
39
40 fn description(&self) -> &str {
41 "Flags hedging language (e.g. `I would argue that`, `..., so to speak`, `to a certain degree`)."
42 }
43}
44
45#[cfg(test)]
46mod tests {
47 use super::Hedging;
48 use crate::linting::tests::assert_lint_count;
49
50 #[test]
51 fn detects_hedging_phrase() {
52 assert_lint_count("I would argue that this is correct.", Hedging::default(), 1);
53 }
54
55 #[test]
56 fn does_not_flag_clean_text() {
57 assert_lint_count("This is clear and direct.", Hedging::default(), 0);
58 }
59
60 #[test]
61 fn lowercase_hedging() {
62 assert_lint_count(
63 "i would argue that the outcome is uncertain.",
64 Hedging::default(),
65 1,
66 );
67 }
68
69 #[test]
70 fn incomplete_phrase_not_flagged() {
71 assert_lint_count("I would argue the data is clear.", Hedging::default(), 0);
72 }
73
74 #[test]
75 fn phrase_with_trailing_comma() {
76 let text = "I would argue that, this method works.";
77 assert_lint_count(text, Hedging::default(), 1);
78 }
79
80 #[test]
81 fn phrase_with_extra_whitespace() {
82 assert_lint_count(
83 "to a certain degree the results are ambiguous.",
84 Hedging::default(),
85 1,
86 );
87 }
88
89 #[test]
90 fn does_not_flag_similar_but_incorrect_phrase() {
91 assert_lint_count(
92 "He spoke so to speakingly about the event.",
93 Hedging::default(),
94 0,
95 );
96 }
97
98 #[test]
99 fn phrase_split_by_line_break() {
100 assert_lint_count(
101 "I would argue\nthat this approach fails.",
102 Hedging::default(),
103 1,
104 );
105 }
106}