harper_core/linting/
hereby.rs1use crate::{
2 Token, TokenStringExt,
3 patterns::{Pattern, SequencePattern},
4};
5
6use super::{Lint, LintKind, PatternLinter, Suggestion};
7
8pub struct Hereby {
9 pattern: Box<dyn Pattern>,
10}
11
12impl Default for Hereby {
13 fn default() -> Self {
14 let pattern = SequencePattern::aco("here")
15 .then_whitespace()
16 .t_aco("by")
17 .then_whitespace()
18 .then_verb();
19
20 Self {
21 pattern: Box::new(pattern),
22 }
23 }
24}
25
26impl PatternLinter for Hereby {
27 fn pattern(&self) -> &dyn Pattern {
28 self.pattern.as_ref()
29 }
30
31 fn match_to_lint(&self, matched_tokens: &[Token], source: &[char]) -> Option<Lint> {
32 let span = matched_tokens[0..3].span()?;
33 let orig_chars = span.get_content(source);
34 Some(Lint {
35 span,
36 lint_kind: LintKind::WordChoice,
37 suggestions: vec![Suggestion::replace_with_match_case(
38 "hereby".chars().collect(),
39 orig_chars,
40 )],
41 message: "Did you mean the closed compound `hereby`?".to_owned(),
42 ..Default::default()
43 })
44 }
45
46 fn description(&self) -> &'static str {
47 "`Here by` in some contexts should be `hereby`"
48 }
49}
50
51#[cfg(test)]
52mod tests {
53 use crate::linting::tests::assert_suggestion_result;
54
55 use super::Hereby;
56
57 #[test]
58 fn declare() {
59 assert_suggestion_result(
60 "I here by declare this state to be free.",
61 Hereby::default(),
62 "I hereby declare this state to be free.",
63 );
64 }
65}