use crate::tokenizer::{XmlTokenizer, XmlTokenizerOpts};
use crate::tree_builder::{TreeSink, XmlTreeBuilder, XmlTreeBuilderOpts};
use std::borrow::Cow;
use crate::tendril;
use crate::tendril::stream::{TendrilSink, Utf8LossyDecoder};
use crate::tendril::StrTendril;
use markup5ever::buffer_queue::BufferQueue;
#[derive(Clone, Default)]
pub struct XmlParseOpts {
pub tokenizer: XmlTokenizerOpts,
pub tree_builder: XmlTreeBuilderOpts,
}
pub fn parse_document<Sink>(sink: Sink, opts: XmlParseOpts) -> XmlParser<Sink>
where
Sink: TreeSink,
{
let tb = XmlTreeBuilder::new(sink, opts.tree_builder);
let tok = XmlTokenizer::new(tb, opts.tokenizer);
XmlParser {
tokenizer: tok,
input_buffer: BufferQueue::new(),
}
}
pub struct XmlParser<Sink>
where
Sink: TreeSink,
{
pub tokenizer: XmlTokenizer<XmlTreeBuilder<Sink::Handle, Sink>>,
pub input_buffer: BufferQueue,
}
impl<Sink: TreeSink> TendrilSink<tendril::fmt::UTF8> for XmlParser<Sink> {
type Output = Sink::Output;
fn process(&mut self, t: StrTendril) {
self.input_buffer.push_back(t);
self.tokenizer.feed(&mut self.input_buffer);
}
fn error(&mut self, desc: Cow<'static, str>) {
self.tokenizer.sink.sink.parse_error(desc)
}
fn finish(mut self) -> Self::Output {
self.tokenizer.end();
self.tokenizer.sink.sink.finish()
}
}
impl<Sink: TreeSink> XmlParser<Sink> {
#[allow(clippy::wrong_self_convention)]
pub fn from_utf8(self) -> Utf8LossyDecoder<Self> {
Utf8LossyDecoder::new(self)
}
}