harper_core/linting/
number_suffix_capitalization.rs

1use super::{Lint, LintKind, Linter, Suggestion};
2use crate::{Document, Span, TokenKind};
3use crate::{Number, TokenStringExt};
4
5/// Detect incorrect capitalization for number suffixes (e.g. "2ND").
6#[derive(Debug, Clone, Copy, Default)]
7pub struct NumberSuffixCapitalization;
8
9impl Linter for NumberSuffixCapitalization {
10    fn lint(&mut self, document: &Document) -> Vec<Lint> {
11        let mut output = Vec::new();
12
13        for number_tok in document.iter_numbers() {
14            if let TokenKind::Number(Number { suffix: None, .. }) = number_tok.kind {
15                continue;
16            }
17
18            let suffix_span = Span::new_with_len(number_tok.span.end, 2)
19                .pulled_by(2)
20                .unwrap();
21            let chars = document.get_span_content(&suffix_span);
22
23            if chars.iter().any(|c| !c.is_lowercase()) {
24                output.push(Lint {
25                    span: suffix_span,
26                    lint_kind: LintKind::Capitalization,
27                    message: "This suffix should be lowercase".to_string(),
28                    suggestions: vec![Suggestion::ReplaceWith(
29                        chars.iter().map(|c| c.to_ascii_lowercase()).collect(),
30                    )],
31                    ..Default::default()
32                })
33            }
34        }
35
36        output
37    }
38
39    fn description(&self) -> &'static str {
40        "You should never capitalize number suffixes."
41    }
42}
43
44#[cfg(test)]
45mod tests {
46    use super::NumberSuffixCapitalization;
47    use crate::linting::tests::assert_lint_count;
48
49    #[test]
50    fn detects_uppercase_suffix() {
51        assert_lint_count("2ND", NumberSuffixCapitalization, 1);
52    }
53
54    #[test]
55    fn detects_inconsistent_suffix() {
56        assert_lint_count("2nD", NumberSuffixCapitalization, 1);
57    }
58
59    #[test]
60    fn passes_correct_case() {
61        assert_lint_count("2nd", NumberSuffixCapitalization, 0);
62    }
63}