mdwright_lint/stdlib/
duplicate_link_label.rs1use std::collections::HashMap;
8
9use crate::diagnostic::Diagnostic;
10use crate::rule::LintRule;
11use mdwright_document::Document;
12
13pub struct DuplicateLinkLabel;
14
15impl LintRule for DuplicateLinkLabel {
16 fn name(&self) -> &str {
17 "duplicate-link-label"
18 }
19
20 fn description(&self) -> &str {
21 "Two `[label]:` definitions with the same label."
22 }
23
24 fn explain(&self) -> &str {
25 include_str!("explain/duplicate_link_label.md")
26 }
27
28 fn check(&self, doc: &Document, out: &mut Vec<Diagnostic>) {
29 let mut seen: HashMap<String, usize> = HashMap::new();
30 for def in doc.link_defs() {
31 let key = def.label.to_ascii_lowercase();
32 match seen.get(&key) {
33 Some(&first_line_byte) => {
34 let message = format!(
35 "duplicate link reference `{}` — first defined at byte {first_line_byte}",
36 def.label
37 );
38 let local = 0..(def.raw_range.end.saturating_sub(def.raw_range.start));
39 if let Some(d) = Diagnostic::at(doc, def.raw_range.start, local, message, None) {
40 out.push(d);
41 }
42 }
43 None => {
44 seen.insert(key, def.raw_range.start);
45 }
46 }
47 }
48 }
49}