diff options
Diffstat (limited to 'src/emitter.rs')
-rw-r--r-- | src/emitter.rs | 45 |
1 files changed, 30 insertions, 15 deletions
diff --git a/src/emitter.rs b/src/emitter.rs index 2c4ba41..20bcba4 100644 --- a/src/emitter.rs +++ b/src/emitter.rs @@ -1,6 +1,7 @@ use std::collections::BTreeMap; use std::collections::BTreeSet; use std::collections::VecDeque; +use std::marker::PhantomData; use std::mem; use crate::Error; @@ -28,7 +29,7 @@ use crate::State; /// /// The state machine needs to have a functional implementation of /// `current_is_appropriate_end_tag_token` to do correct transitions, however. -pub trait Emitter { +pub trait Emitter<R> { /// The token type emitted by this emitter. This controls what type of values the [`crate::Tokenizer`] /// yields when used as an iterator. type Token; @@ -54,13 +55,13 @@ pub trait Emitter { fn emit_string(&mut self, c: &str); /// Set the _current token_ to a start tag. - fn init_start_tag(&mut self); + fn init_start_tag(&mut self, reader: &R); /// Set the _current token_ to an end tag. - fn init_end_tag(&mut self); + fn init_end_tag(&mut self, reader: &R); /// Set the _current token_ to a comment. - fn init_comment(&mut self); + fn init_comment(&mut self, reader: &R); /// Emit the _current token_, assuming it is a tag. /// @@ -116,7 +117,7 @@ pub trait Emitter { /// * the "public identifier" should be null (different from empty) /// * the "system identifier" should be null (different from empty) /// * the "force quirks" flag should be `false` - fn init_doctype(&mut self); + fn init_doctype(&mut self, reader: &R); /// Set the _current attribute_ to a new one, starting with empty name and value strings. /// @@ -128,7 +129,7 @@ pub trait Emitter { /// emitted. /// /// If the current token is no tag at all, this method may panic. - fn init_attribute(&mut self); + fn init_attribute(&mut self, reader: &R); /// Append a string to the current attribute's name. /// @@ -172,17 +173,31 @@ pub trait Emitter { } /// The default implementation of [`crate::Emitter`], used to produce ("emit") tokens. -#[derive(Default)] -pub struct DefaultEmitter<S> { +pub struct DefaultEmitter<R, S> { current_characters: String, current_token: Option<Token<S>>, last_start_tag: String, current_attribute: Option<(String, String)>, seen_attributes: BTreeSet<String>, emitted_tokens: VecDeque<Token<S>>, + reader: PhantomData<R>, } -impl DefaultEmitter<()> { +impl<R, S> Default for DefaultEmitter<R, S> { + fn default() -> Self { + DefaultEmitter { + current_characters: String::new(), + current_token: None, + last_start_tag: String::new(), + current_attribute: None, + seen_attributes: BTreeSet::new(), + emitted_tokens: VecDeque::new(), + reader: PhantomData::default(), + } + } +} + +impl<R> DefaultEmitter<R, ()> { fn emit_token(&mut self, token: Token<()>) { self.flush_current_characters(); self.emitted_tokens.push_front(token); @@ -226,7 +241,7 @@ impl DefaultEmitter<()> { } } -impl Emitter for DefaultEmitter<()> { +impl<R> Emitter<R> for DefaultEmitter<R, ()> { type Token = Token<()>; fn set_last_start_tag(&mut self, last_start_tag: Option<&str>) { @@ -253,15 +268,15 @@ impl Emitter for DefaultEmitter<()> { self.current_characters.push_str(s); } - fn init_start_tag(&mut self) { + fn init_start_tag(&mut self, _reader: &R) { self.current_token = Some(Token::StartTag(Default::default())); } - fn init_end_tag(&mut self) { + fn init_end_tag(&mut self, _reader: &R) { self.current_token = Some(Token::EndTag(Default::default())); self.seen_attributes.clear(); } - fn init_comment(&mut self) { + fn init_comment(&mut self, _reader: &R) { self.current_token = Some(Token::Comment(String::new())); } fn emit_current_tag(&mut self) { @@ -341,7 +356,7 @@ impl Emitter for DefaultEmitter<()> { _ => debug_assert!(false), } } - fn init_doctype(&mut self) { + fn init_doctype(&mut self, _reader: &R) { self.current_token = Some(Token::Doctype(Doctype { name: String::new(), force_quirks: false, @@ -350,7 +365,7 @@ impl Emitter for DefaultEmitter<()> { })); } - fn init_attribute(&mut self) { + fn init_attribute(&mut self, _reader: &R) { self.flush_current_attribute(); self.current_attribute = Some((String::new(), String::new())); } |