use miette::Diagnostic; use thiserror::Error; use crate::{ diagnostics::AstDiagnostic, parse::Node, tokenize::{Span, TokenType}, }; #[derive(Error, Debug, Diagnostic)] #[error("Top-level character data is present")] #[diagnostic(code(TopLevelCharacterData), severity(Error))] pub struct TopLevelCharacterData { #[label(collection)] nodes: Vec, } impl AstDiagnostic for TopLevelCharacterData { fn handle_document(document: &crate::parse::Document<'_>) -> Option { let cdata_nodes = document .children .iter() .filter_map(|node| { if let Node::CharacterData(token) = node && let TokenType::Data(data) = token.ty && data.chars().any(|c| !c.is_whitespace()) { Some(token.span) } else { None } }) .collect::>(); if cdata_nodes.is_empty() { return None; } Some(Self { nodes: cdata_nodes }) } }