mdwright_lint/stdlib/
inconsistent_list_marker.rs1use crate::diagnostic::{Diagnostic, Fix};
9use crate::rule::LintRule;
10use mdwright_document::Document;
11
12pub struct InconsistentListMarker;
13
14impl LintRule for InconsistentListMarker {
15 fn name(&self) -> &str {
16 "inconsistent-list-marker"
17 }
18
19 fn description(&self) -> &str {
20 "Mixed `-` / `*` / `+` markers in one bullet list."
21 }
22
23 fn explain(&self) -> &str {
24 include_str!("explain/inconsistent_list_marker.md")
25 }
26
27 fn produces_fix(&self) -> bool {
28 true
29 }
30
31 fn check(&self, doc: &Document, out: &mut Vec<Diagnostic>) {
32 for group in doc.list_groups() {
33 if group.ordered || group.items.is_empty() {
34 continue;
35 }
36 let Some(first) = group.items.first() else {
37 continue;
38 };
39 let expected = first.marker_byte;
40 for item in group.items.iter().skip(1) {
41 if item.marker_byte != expected {
42 let actual = item.marker_byte as char;
43 let expected_c = expected as char;
44 let message = format!(
45 "list marker `{actual}` does not match first item's `{expected_c}` \
46 — keep one marker per list"
47 );
48 let start = item.raw_range.start;
49 let local = 0..1;
50 let fix = Some(Fix {
51 replacement: expected_c.to_string(),
52 safe: true,
53 });
54 if let Some(d) = Diagnostic::at(doc, start, local, message, fix) {
55 out.push(d);
56 }
57 }
58 }
59 }
60 }
61}