harper_core/linting/
for_noun.rs

1use crate::{
2    Token,
3    patterns::{NominalPhrase, OwnedPatternExt, Pattern, SequencePattern, Word},
4};
5
6use super::{Lint, LintKind, PatternLinter, Suggestion};
7
8pub struct ForNoun {
9    pattern: Box<dyn Pattern>,
10}
11
12impl Default for ForNoun {
13    fn default() -> Self {
14        let pattern = SequencePattern::aco("fro")
15            .then_whitespace()
16            .then(NominalPhrase.or(Box::new(Word::new("sure"))));
17
18        Self {
19            pattern: Box::new(pattern),
20        }
21    }
22}
23
24impl PatternLinter for ForNoun {
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.first()?.span;
31        let problem_chars = span.get_content(source);
32
33        Some(Lint {
34            span,
35            lint_kind: LintKind::WordChoice,
36            suggestions: vec![Suggestion::replace_with_match_case_str(
37                "for",
38                problem_chars,
39            )],
40            message: "`For` is more common in this context.".to_owned(),
41            priority: 31,
42        })
43    }
44
45    fn description(&self) -> &'static str {
46        "Corrects the archaic or mistaken `fro` to `for` when followed by a noun."
47    }
48}
49
50#[cfg(test)]
51mod tests {
52    use super::ForNoun;
53    use crate::linting::tests::{assert_lint_count, assert_suggestion_result};
54
55    #[test]
56    fn corrects_fro_basic_correction() {
57        assert_suggestion_result(
58            "I got a text fro Sarah.",
59            ForNoun::default(),
60            "I got a text for Sarah.",
61        );
62    }
63
64    #[test]
65    fn allows_for_clean() {
66        assert_lint_count("I got a text for Sarah.", ForNoun::default(), 0);
67    }
68
69    #[test]
70    fn corrects_fro_sure() {
71        assert_suggestion_result(
72            "He was away fro sure!",
73            ForNoun::default(),
74            "He was away for sure!",
75        );
76    }
77}