harper_core/linting/
number_suffix_capitalization.rs1use super::{Lint, LintKind, Linter, Suggestion};
2use crate::{Document, Span, TokenKind};
3use crate::{Number, TokenStringExt};
4
5#[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}