use vize_armature::tokenizer::{Callbacks, QuoteType};
use vize_l0::Vec;
use vize_relief::ErrorCode;
use crate::parse::SurfaceError;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub(crate) enum EventKind {
Text,
Interpolation,
OpenTagName,
OpenTagEnd,
SelfClosingTag,
CloseTag,
AttrName,
AttrNameEnd,
AttrData,
AttrEnd,
Comment,
Cdata,
ProcessingInstruction,
}
#[derive(Debug, Clone, Copy)]
pub(crate) struct Event {
pub kind: EventKind,
pub aux: u8,
pub start: u32,
pub end: u32,
}
impl Event {
fn new(kind: EventKind, start: usize, end: usize) -> Self {
Self {
kind,
aux: 0,
start: start as u32,
end: end as u32,
}
}
pub(crate) fn quote(&self) -> QuoteType {
debug_assert!(self.kind == EventKind::AttrEnd);
match self.aux {
1 => QuoteType::Unquoted,
2 => QuoteType::Single,
3 => QuoteType::Double,
_ => QuoteType::NoValue,
}
}
}
pub(crate) struct Recorder<'a, 'v> {
pub events: &'v mut Vec<'a, Event>,
pub errors: &'v mut Vec<'a, SurfaceError>,
}
impl Recorder<'_, '_> {
fn push(&mut self, kind: EventKind, start: usize, end: usize) {
self.events.push(Event::new(kind, start, end));
}
}
impl Callbacks for Recorder<'_, '_> {
fn on_text(&mut self, start: usize, end: usize) {
self.push(EventKind::Text, start, end);
}
fn on_text_entity(&mut self, _char: char, start: usize, end: usize) {
self.push(EventKind::Text, start, end);
}
fn on_interpolation(&mut self, start: usize, end: usize) {
self.push(EventKind::Interpolation, start, end);
}
fn on_open_tag_name(&mut self, start: usize, end: usize) {
self.push(EventKind::OpenTagName, start, end);
}
fn on_open_tag_end(&mut self, end: usize) {
self.push(EventKind::OpenTagEnd, end, end);
}
fn on_self_closing_tag(&mut self, end: usize) {
self.push(EventKind::SelfClosingTag, end, end);
}
fn on_close_tag(&mut self, start: usize, end: usize) {
self.push(EventKind::CloseTag, start, end);
}
fn on_attrib_data(&mut self, start: usize, end: usize) {
self.push(EventKind::AttrData, start, end);
}
fn on_attrib_entity(&mut self, _char: char, start: usize, end: usize) {
self.push(EventKind::AttrData, start, end);
}
fn on_attrib_end(&mut self, quote: QuoteType, end: usize) {
self.events.push(Event {
kind: EventKind::AttrEnd,
aux: quote as u8,
start: end as u32,
end: end as u32,
});
}
fn on_attrib_name(&mut self, start: usize, end: usize) {
self.push(EventKind::AttrName, start, end);
}
fn on_attrib_name_end(&mut self, end: usize) {
self.push(EventKind::AttrNameEnd, end, end);
}
fn on_dir_name(&mut self, start: usize, end: usize) {
self.push(EventKind::AttrName, start, end);
}
fn on_dir_arg(&mut self, start: usize, end: usize) {
self.push(EventKind::AttrName, start, end);
}
fn on_dir_modifier(&mut self, start: usize, end: usize) {
self.push(EventKind::AttrName, start, end);
}
fn on_comment(&mut self, start: usize, end: usize) {
self.push(EventKind::Comment, start, end);
}
fn on_cdata(&mut self, start: usize, end: usize) {
self.push(EventKind::Cdata, start, end);
}
fn on_processing_instruction(&mut self, start: usize, end: usize) {
self.push(EventKind::ProcessingInstruction, start, end);
}
fn on_end(&mut self) {}
fn on_error(&mut self, code: ErrorCode, index: usize) {
self.errors.push(SurfaceError {
code,
offset: index as u32,
});
}
}