use std::collections::HashMap; use miette::Diagnostic; use thiserror::Error; use crate::{ diagnostics::AstDiagnostic, parse::{Attribute, Element}, tokenize::Span, }; #[derive(Error, Debug, Diagnostic)] #[error("Multiple attributes have the same name")] #[diagnostic(code(DuplicateAttributeNames), severity(Error))] pub struct DuplicateAttributeNames { #[label(collection)] duplicates: Vec, } impl AstDiagnostic for DuplicateAttributeNames { fn handle_element(element: &Element<'_>) -> Option { let mut seen_attributes = HashMap::<&str, Attribute<'_>>::new(); for attribute in element.attributes { let Some(name) = attribute.name_lowercase() else { continue; }; if let Some(duplicate) = seen_attributes.get(name) { return Some(Self { duplicates: vec![ duplicate.name_token().expect("a named attribute").span, attribute.name_token().expect("a named attribute").span, ], }); } seen_attributes.insert(name, *attribute); } None } }