@@ -22,16 +22,16 @@ use self::states::{Rawtext, Rcdata, ScriptData, ScriptDataEscaped};
2222use self :: char_ref:: { CharRef , CharRefTokenizer } ;
2323
2424use crate :: util:: str:: lower_ascii_letter;
25-
2625use log:: { debug, trace} ;
2726use mac:: format_if;
28- use markup5ever:: { namespace_url, ns, small_char_set} ;
27+ use markup5ever:: buffer_queue:: BufferQueue ;
28+ use markup5ever:: { namespace_url, ns, small_char_set, InputSink , InputSinkResult } ;
2929use std:: borrow:: Cow :: { self , Borrowed } ;
3030use std:: cell:: { Cell , RefCell , RefMut } ;
3131use std:: collections:: BTreeMap ;
32- use std:: mem;
32+ use std:: { iter , mem} ;
3333
34- pub use crate :: buffer_queue:: { BufferQueue , FromSet , NotFromSet , SetResult } ;
34+ pub use crate :: buffer_queue:: { FromSet , NotFromSet , SetResult } ;
3535use crate :: tendril:: StrTendril ;
3636use crate :: { Attribute , LocalName , QualName , SmallCharSet } ;
3737
@@ -43,13 +43,17 @@ pub enum ProcessResult<Handle> {
4343 Continue ,
4444 Suspend ,
4545 Script ( Handle ) ,
46+ #[ cfg( feature = "encoding" ) ]
47+ MaybeChangeEncodingAndStartOver ( & ' static encoding_rs:: Encoding )
4648}
4749
4850#[ must_use]
4951#[ derive( Debug ) ]
5052pub enum TokenizerResult < Handle > {
5153 Done ,
5254 Script ( Handle ) ,
55+ #[ cfg( feature = "encoding" ) ]
56+ MaybeChangeEncodingAndStartOver ( & ' static encoding_rs:: Encoding )
5357}
5458
5559fn option_push ( opt_str : & mut Option < StrTendril > , c : char ) {
@@ -364,6 +368,8 @@ impl<Sink: TokenSink> Tokenizer<Sink> {
364368 ProcessResult :: Continue => ( ) ,
365369 ProcessResult :: Suspend => break ,
366370 ProcessResult :: Script ( node) => return TokenizerResult :: Script ( node) ,
371+ #[ cfg( feature = "encoding" ) ]
372+ ProcessResult :: MaybeChangeEncodingAndStartOver ( encoding) => return TokenizerResult :: MaybeChangeEncodingAndStartOver ( encoding) ,
367373 }
368374 }
369375 } else {
@@ -372,6 +378,8 @@ impl<Sink: TokenSink> Tokenizer<Sink> {
372378 ProcessResult :: Continue => ( ) ,
373379 ProcessResult :: Suspend => break ,
374380 ProcessResult :: Script ( node) => return TokenizerResult :: Script ( node) ,
381+ #[ cfg( feature = "encoding" ) ]
382+ ProcessResult :: MaybeChangeEncodingAndStartOver ( encoding) => return TokenizerResult :: MaybeChangeEncodingAndStartOver ( encoding) ,
375383 }
376384 }
377385 }
@@ -452,6 +460,8 @@ impl<Sink: TokenSink> Tokenizer<Sink> {
452460 self . state . set ( states:: RawData ( kind) ) ;
453461 ProcessResult :: Continue
454462 } ,
463+ #[ cfg( feature = "encoding" ) ]
464+ TokenSinkResult :: MaybeChangeEncodingAndStartOver ( encoding) => ProcessResult :: MaybeChangeEncodingAndStartOver ( encoding)
455465 }
456466 }
457467
@@ -1455,6 +1465,8 @@ impl<Sink: TokenSink> Tokenizer<Sink> {
14551465 ProcessResult :: Continue => ( ) ,
14561466 ProcessResult :: Suspend => break ,
14571467 ProcessResult :: Script ( _) => unreachable ! ( ) ,
1468+ #[ cfg( feature = "encoding" ) ]
1469+ ProcessResult :: MaybeChangeEncodingAndStartOver ( _) => unreachable ! ( ) ,
14581470 }
14591471 }
14601472
@@ -1582,13 +1594,34 @@ impl<Sink: TokenSink> Tokenizer<Sink> {
15821594 }
15831595}
15841596
1597+ impl < Sink > InputSink for Tokenizer < Sink >
1598+ where Sink : TokenSink {
1599+ type Handle = Sink :: Handle ;
1600+
1601+ fn feed ( & self , input : & BufferQueue ) -> impl Iterator < Item = InputSinkResult < Self :: Handle > > {
1602+ iter:: from_fn ( || {
1603+ self . feed ( input) . into ( )
1604+ } )
1605+ }
1606+ }
1607+
1608+ impl < Handle > From < TokenizerResult < Handle > > for Option < InputSinkResult < Handle > > {
1609+ fn from ( value : TokenizerResult < Handle > ) -> Self {
1610+ match value {
1611+ TokenizerResult :: Script ( handle) => Some ( InputSinkResult :: HandleScript ( handle) ) ,
1612+ TokenizerResult :: MaybeChangeEncodingAndStartOver ( encoding) => Some ( InputSinkResult :: MaybeStartOverWithEncoding ( encoding) ) ,
1613+ TokenizerResult :: Done => None ,
1614+ }
1615+ }
1616+ }
1617+
15851618#[ cfg( test) ]
15861619#[ allow( non_snake_case) ]
15871620mod test {
15881621 use super :: option_push; // private items
1589- use crate :: tendril:: { SliceExt , StrTendril } ;
1590-
15911622 use super :: { TokenSink , TokenSinkResult , Tokenizer , TokenizerOpts } ;
1623+ use crate :: tendril:: { SliceExt , StrTendril } ;
1624+ use crate :: LocalName ;
15921625
15931626 use super :: interface:: { CharacterTokens , EOFToken , NullCharacterToken , ParseError } ;
15941627 use super :: interface:: { EndTag , StartTag , Tag , TagKind } ;
@@ -1597,8 +1630,6 @@ mod test {
15971630 use markup5ever:: buffer_queue:: BufferQueue ;
15981631 use std:: cell:: RefCell ;
15991632
1600- use crate :: LocalName ;
1601-
16021633 // LinesMatch implements the TokenSink trait. It is used for testing to see
16031634 // if current_line is being updated when process_token is called. The lines
16041635 // vector is a collection of the line numbers that each token is on.
0 commit comments