use vize_l0::{Box, Vec};
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum TokenStatus {
Present,
Missing,
}
#[derive(Debug, Clone, Copy)]
pub struct Token<'a> {
pub leading: &'a str,
pub text: &'a str,
pub status: TokenStatus,
}
impl<'a> Token<'a> {
pub(crate) fn present(leading: &'a str, text: &'a str) -> Self {
Self {
leading,
text,
status: TokenStatus::Present,
}
}
pub(crate) fn missing(leading: &'a str, at: &'a str) -> Self {
debug_assert!(at.is_empty());
Self {
leading,
text: at,
status: TokenStatus::Missing,
}
}
pub fn is_missing(&self) -> bool {
self.status == TokenStatus::Missing
}
}
#[derive(Debug)]
pub enum SurfaceChild<'a> {
Element(Box<'a, Element<'a>>),
Text(Token<'a>),
Interpolation(Box<'a, Interpolation<'a>>),
Comment(Token<'a>),
Cdata(Token<'a>),
ProcessingInstruction(Token<'a>),
Unexpected(Token<'a>),
}
#[derive(Debug)]
pub struct Interpolation<'a> {
pub open: Token<'a>,
pub content: Token<'a>,
pub close: Token<'a>,
}
#[derive(Debug)]
pub struct Element<'a> {
pub open: OpenTag<'a>,
pub children: Vec<'a, SurfaceChild<'a>>,
pub close: ElementClose<'a>,
}
impl<'a> Element<'a> {
pub fn tag(&self) -> &'a str {
let text = self.open.lt_name.text;
text.get(1..).unwrap_or(text)
}
}
#[derive(Debug)]
pub struct OpenTag<'a> {
pub lt_name: Token<'a>,
pub attrs: Vec<'a, Attribute<'a>>,
pub slash: Option<Token<'a>>,
pub gt: Token<'a>,
}
#[derive(Debug)]
pub enum ElementClose<'a> {
Present(CloseTag<'a>),
Implicit,
Missing,
NotExpected,
}
#[derive(Debug)]
pub struct CloseTag<'a> {
pub lt_slash_name: Token<'a>,
pub gt: Token<'a>,
}
#[derive(Debug)]
pub struct Attribute<'a> {
pub name: Token<'a>,
pub eq: Option<Token<'a>>,
pub value: Option<AttrValue<'a>>,
}
#[derive(Debug)]
pub struct AttrValue<'a> {
pub open_quote: Option<Token<'a>>,
pub content: Token<'a>,
pub close_quote: Option<Token<'a>>,
}
impl<'a> AttrValue<'a> {
pub(crate) fn unquoted(content: Token<'a>) -> Self {
Self {
open_quote: None,
content,
close_quote: None,
}
}
}
#[derive(Debug)]
pub struct SurfaceTree<'a> {
pub source: &'a str,
pub children: Vec<'a, SurfaceChild<'a>>,
}
#[cfg(target_pointer_width = "64")]
const _: () = {
assert!(size_of::<Token<'_>>() == 40);
assert!(size_of::<Option<Token<'_>>>() == 40);
assert!(size_of::<Interpolation<'_>>() == 120);
assert!(size_of::<Attribute<'_>>() == 200);
assert!(size_of::<AttrValue<'_>>() == 120);
assert!(size_of::<OpenTag<'_>>() == 144);
assert!(size_of::<CloseTag<'_>>() == 80);
assert!(size_of::<ElementClose<'_>>() == 80);
assert!(size_of::<Element<'_>>() == 248);
assert!(size_of::<SurfaceChild<'_>>() == 48);
assert!(size_of::<SurfaceTree<'_>>() == 40);
};