harper_core/linting/lint_kind.rs
1use std::fmt::Display;
2
3use is_macro::Is;
4use serde::{Deserialize, Serialize};
5
6/// The general category a [`Lint`](super::Lint) falls into.
7/// There's no reason not to add a new item here if you are adding a new rule that doesn't fit
8/// the existing categories.
9#[derive(Debug, Clone, Copy, Serialize, Deserialize, Is, Default, Hash, PartialEq, Eq)]
10pub enum LintKind {
11 Agreement,
12 /// For errors where words are joined or split at the wrong boundaries
13 /// (e.g., "each and everyone" vs. "each and every one")
14 BoundaryError,
15 Capitalization,
16 /// For cases where a word or phrase is misused for a similar-sounding word or phrase,
17 /// where the incorrect version makes logical sense (e.g., 'egg corn' for 'acorn',
18 /// 'on mass' for 'en masse').
19 Eggcorn,
20 /// For suggesting improvements that enhance clarity or impact without fixing errors
21 Enhancement,
22 Formatting,
23 Grammar,
24 /// For cases where a word is mistakenly used for a similar-sounding word with a different meaning
25 /// (e.g., 'eluded to' instead of 'alluded to'). Unlike eggcorns, these don't create new meanings.
26 Malapropism,
27 /// For any other lint that doesn't fit neatly into the other categories
28 #[default]
29 Miscellaneous,
30 Nonstandard,
31 /// For issues with punctuation, including hyphenation in compound adjectives
32 /// (e.g., "face first" vs. "face-first" when used before a noun)
33 Punctuation,
34 Readability,
35 /// For cases where words duplicate meaning that's already expressed
36 /// (e.g., "basic fundamentals" → "fundamentals", "free gift" → "gift")
37 Redundancy,
38 /// For variations that are standard in some regions or dialects but not others
39 Regionalism,
40 Repetition,
41 /// When your brain doesn't know the right spelling.
42 /// This should only be used by linters doing spellcheck on individual words.
43 Spelling,
44 /// For cases where multiple options are correct but one is preferred for style or clarity,
45 /// such as expanding abbreviations in formal writing (e.g., 'min' → 'minimum')
46 Style,
47 /// When your brain knows the right spelling but your fingers made a mistake.
48 /// (e.g., 'can be seem' → 'can be seen')
49 Typo,
50 /// For conventional word usage and standard collocations
51 /// (e.g., 'by accident' vs. 'on accident' in standard English)
52 Usage,
53 /// For choosing between different words or phrases in a given context
54 WordChoice,
55}
56
57impl LintKind {
58 /// Produce a string representation, which can be used as keys in a map or CSS variables.
59 pub fn to_string_key(&self) -> String {
60 match self {
61 LintKind::Agreement => "Agreement",
62 LintKind::BoundaryError => "BoundaryError",
63 LintKind::Capitalization => "Capitalization",
64 LintKind::Eggcorn => "Eggcorn",
65 LintKind::Enhancement => "Enhancement",
66 LintKind::Formatting => "Formatting",
67 LintKind::Grammar => "Grammar",
68 LintKind::Malapropism => "Malapropism",
69 LintKind::Miscellaneous => "Miscellaneous",
70 LintKind::Nonstandard => "Nonstandard",
71 LintKind::Punctuation => "Punctuation",
72 LintKind::Readability => "Readability",
73 LintKind::Redundancy => "Redundancy",
74 LintKind::Regionalism => "Regionalism",
75 LintKind::Repetition => "Repetition",
76 LintKind::Spelling => "Spelling",
77 LintKind::Style => "Style",
78 LintKind::Typo => "Typo",
79 LintKind::Usage => "Usage",
80 LintKind::WordChoice => "WordChoice",
81 }
82 .to_owned()
83 }
84}
85
86impl Display for LintKind {
87 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
88 let s = match self {
89 LintKind::Agreement => "Agreement",
90 LintKind::BoundaryError => "BoundaryError",
91 LintKind::Capitalization => "Capitalization",
92 LintKind::Eggcorn => "Eggcorn",
93 LintKind::Enhancement => "Enhancement",
94 LintKind::Formatting => "Formatting",
95 LintKind::Grammar => "Grammar",
96 LintKind::Malapropism => "Malapropism",
97 LintKind::Miscellaneous => "Miscellaneous",
98 LintKind::Nonstandard => "Nonstandard",
99 LintKind::Punctuation => "Punctuation",
100 LintKind::Readability => "Readability",
101 LintKind::Redundancy => "Redundancy",
102 LintKind::Regionalism => "Regionalism",
103 LintKind::Repetition => "Repetition",
104 LintKind::Spelling => "Spelling",
105 LintKind::Style => "Style",
106 LintKind::Typo => "Typo",
107 LintKind::Usage => "Usage",
108 LintKind::WordChoice => "Word Choice",
109 };
110
111 write!(f, "{s}")
112 }
113}