use crate::offset::{Offset, Position};
use crate::reader::{IntoReader, Reader};
use crate::{BasicEmitter, Emitter, Event, State, Tokenizer};
pub struct NaiveParser<R: Reader, O: Offset, E: Emitter<O>> {
tokenizer: Tokenizer<R, O, E>,
}
impl<R, O> NaiveParser<R, O, BasicEmitter<O>>
where
R: Reader + Position<O>,
O: Offset,
{
pub fn new<'a, IR>(reader: IR) -> NaiveParser<R, O, BasicEmitter<O>>
where
IR: IntoReader<'a, Reader = R>,
{
NaiveParser::new_with_emitter(reader, BasicEmitter::default())
}
}
impl<R, O, E> NaiveParser<R, O, E>
where
R: Reader + Position<O>,
O: Offset,
E: Emitter<O>,
{
pub fn new_with_emitter<'a, IR>(reader: IR, emitter: E) -> NaiveParser<R, O, E>
where
IR: IntoReader<'a, Reader = R>,
{
let mut tokenizer = Tokenizer::new(reader, emitter);
tokenizer.enable_naive_state_switching();
NaiveParser { tokenizer }
}
pub fn emitter_mut(&mut self) -> &mut E {
self.tokenizer.emitter_mut()
}
}
impl<R, O, E> Iterator for NaiveParser<R, O, E>
where
R: Reader + Position<O>,
O: Offset,
E: Emitter<O> + Iterator,
{
type Item = Result<E::Item, R::Error>;
fn next(&mut self) -> Option<Self::Item> {
loop {
let event = self.tokenizer.next()?;
match event {
Err(e) => return Some(Err(e)),
Ok(Event::Token(t)) => {
return Some(Ok(t));
}
Ok(Event::CdataOpen) => {
self.tokenizer.handle_cdata_open(false)
}
}
}
}
}
pub(crate) fn naive_next_state(tag_name: &str) -> State {
match tag_name {
"title" | "textarea" => State::Rcdata,
"style" | "xmp" | "iframe" | "noembed" | "noframes" => State::Rawtext,
"script" => State::ScriptData,
"plaintext" => State::Plaintext,
_other => State::Data,
}
}