harper_core/linting/
ellipsis_length.rs

1use itertools::Itertools;
2
3use super::{Lint, LintKind, Linter, Suggestion};
4use crate::TokenStringExt;
5
6/// A linter that checks that an ellipsis doesn't contain too many periods (or
7/// too few).
8#[derive(Debug, Default)]
9pub struct EllipsisLength;
10
11impl Linter for EllipsisLength {
12    fn lint(&mut self, document: &crate::Document) -> Vec<Lint> {
13        let mut lints = Vec::new();
14
15        for tok in document.iter_ellipsiss() {
16            let tok_content = document.get_span_content(&tok.span);
17
18            if tok_content.is_empty() {
19                continue;
20            }
21
22            if tok_content.first().cloned() == Some('.')
23                && tok_content.iter().all_equal()
24                && tok_content.len() != 3
25            {
26                lints.push(Lint {
27                    span: tok.span,
28                    lint_kind: LintKind::Formatting,
29                    suggestions: vec![Suggestion::ReplaceWith(vec!['.', '.', '.'])],
30                    message: "Horizontal ellipsis must have 3 dots.".to_string(),
31                    priority: 31,
32                })
33            }
34        }
35
36        lints
37    }
38
39    fn description(&self) -> &'static str {
40        "Make sure you have the correct number of dots in your ellipsis."
41    }
42}
43
44#[cfg(test)]
45mod tests {
46    use super::EllipsisLength;
47    use crate::linting::tests::{assert_lint_count, assert_suggestion_result};
48
49    #[test]
50    fn allows_correct_ellipsis() {
51        assert_lint_count("...", EllipsisLength, 0);
52    }
53
54    #[test]
55    fn corrects_long_ellipsis() {
56        assert_lint_count(".....", EllipsisLength, 1);
57        assert_suggestion_result(".....", EllipsisLength, "...");
58    }
59
60    #[test]
61    fn corrects_short_ellipsis() {
62        assert_lint_count("..", EllipsisLength, 1);
63        assert_suggestion_result("..", EllipsisLength, "...");
64    }
65}