diff options
| author | Mica White <botahamec@outlook.com> | 2026-07-12 19:49:14 -0400 |
|---|---|---|
| committer | Mica White <botahamec@outlook.com> | 2026-07-12 19:49:14 -0400 |
| commit | 8399983fd45bc0f11eac9def280c0833ffb93c04 (patch) | |
| tree | f84173ca30a3c62db7abb92a0d869ff5d5199c51 /src/diagnostics/top_level_character_data.rs | |
Diffstat (limited to 'src/diagnostics/top_level_character_data.rs')
| -rw-r--r-- | src/diagnostics/top_level_character_data.rs | 41 |
1 files changed, 41 insertions, 0 deletions
diff --git a/src/diagnostics/top_level_character_data.rs b/src/diagnostics/top_level_character_data.rs new file mode 100644 index 0000000..5deb595 --- /dev/null +++ b/src/diagnostics/top_level_character_data.rs @@ -0,0 +1,41 @@ +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<Span>, +} + +impl AstDiagnostic for TopLevelCharacterData { + fn handle_document(document: &crate::parse::Document<'_>) -> Option<Self> { + 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::<Vec<_>>(); + + if cdata_nodes.is_empty() { + return None; + } + + Some(Self { nodes: cdata_nodes }) + } +} |
