@@ -6,7 +6,6 @@ use std::ops::Range;
66use std:: ascii:: AsciiExt ;
77use std:: ops:: BitOr ;
88use std:: borrow:: Cow ;
9- use std:: ops;
109use tokenizer:: { self , Token , NumericValue , PercentageValue , Tokenizer , SourceLocation } ;
1110
1211
@@ -61,46 +60,21 @@ impl<'a, T> ParseError<'a, T> {
6160 }
6261}
6362
64- /// Like std::borrow::Cow, except the borrowed variant contains a mutable
65- /// reference.
66- enum MaybeOwned < ' a , T : ' a > {
67- Owned ( T ) ,
68- Borrowed ( & ' a mut T ) ,
69- }
70-
71- impl < ' a , T > ops:: Deref for MaybeOwned < ' a , T > {
72- type Target = T ;
73-
74- fn deref < ' b > ( & ' b self ) -> & ' b T {
75- match * self {
76- MaybeOwned :: Owned ( ref t) => t,
77- MaybeOwned :: Borrowed ( ref pointer) => & * * pointer,
78- }
79- }
80- }
81-
82- impl < ' a , T > ops:: DerefMut for MaybeOwned < ' a , T > {
83- fn deref_mut < ' b > ( & ' b mut self ) -> & ' b mut T {
84- match * self {
85- MaybeOwned :: Owned ( ref mut t) => t,
86- MaybeOwned :: Borrowed ( ref mut pointer) => & mut * * pointer,
87- }
88- }
89- }
63+ /// The owned input for a parser.
64+ pub struct ParserInput < ' t > ( Tokenizer < ' t > ) ;
9065
91- impl < ' a , T > Clone for MaybeOwned < ' a , T > where T : Clone {
92- fn clone ( & self ) -> MaybeOwned < ' a , T > {
93- MaybeOwned :: Owned ( ( * * self ) . clone ( ) )
66+ impl < ' t > ParserInput < ' t > {
67+ /// Create a new input for a parser.
68+ pub fn new ( input : & ' t str ) -> ParserInput < ' t > {
69+ ParserInput ( Tokenizer :: new ( input) )
9470 }
9571}
9672
97-
9873/// A CSS parser that borrows its `&str` input,
9974/// yields `Token`s,
10075/// and keeps track of nested blocks and functions.
101- #[ derive( Clone ) ]
10276pub struct Parser < ' i : ' t , ' t > {
103- tokenizer : MaybeOwned < ' t , Tokenizer < ' i > > ,
77+ tokenizer : & ' t mut ParserInput < ' i > ,
10478 /// If `Some(_)`, .parse_nested_block() can be called.
10579 at_start_of : Option < BlockType > ,
10680 /// For parsers from `parse_until` or `parse_nested_block`
@@ -203,12 +177,12 @@ impl Delimiters {
203177 }
204178}
205179
206- impl < ' i , ' t > Parser < ' i , ' t > {
180+ impl < ' i : ' t , ' t > Parser < ' i , ' t > {
207181 /// Create a new parser
208182 #[ inline]
209- pub fn new ( input : & ' i str ) -> Parser < ' i , ' i > {
183+ pub fn new ( input : & ' t mut ParserInput < ' i > ) -> Parser < ' i , ' t > {
210184 Parser {
211- tokenizer : MaybeOwned :: Owned ( Tokenizer :: new ( input) ) ,
185+ tokenizer : input,
212186 at_start_of : None ,
213187 stop_before : Delimiter :: None ,
214188 }
@@ -244,7 +218,7 @@ impl<'i, 't> Parser<'i, 't> {
244218 #[ inline]
245219 pub fn position ( & self ) -> SourcePosition {
246220 SourcePosition {
247- position : self . tokenizer . position ( ) ,
221+ position : ( self . tokenizer . 0 ) . position ( ) ,
248222 at_start_of : self . at_start_of ,
249223 }
250224 }
@@ -255,35 +229,35 @@ impl<'i, 't> Parser<'i, 't> {
255229 /// Should only be used with `SourcePosition` values from the same `Parser` instance.
256230 #[ inline]
257231 pub fn reset ( & mut self , new_position : SourcePosition ) {
258- self . tokenizer . reset ( new_position. position ) ;
232+ ( self . tokenizer . 0 ) . reset ( new_position. position ) ;
259233 self . at_start_of = new_position. at_start_of ;
260234 }
261235
262236 /// Start looking for `var()` functions. (See the `.seen_var_functions()` method.)
263237 #[ inline]
264238 pub fn look_for_var_functions ( & mut self ) {
265- self . tokenizer . look_for_var_functions ( )
239+ ( self . tokenizer . 0 ) . look_for_var_functions ( )
266240 }
267241
268242 /// Return whether a `var()` function has been seen by the tokenizer since
269243 /// either `look_for_var_functions` was called, and stop looking.
270244 #[ inline]
271245 pub fn seen_var_functions ( & mut self ) -> bool {
272- self . tokenizer . seen_var_functions ( )
246+ ( self . tokenizer . 0 ) . seen_var_functions ( )
273247 }
274248
275249 /// Start looking for viewport percentage lengths. (See the `seen_viewport_percentages`
276250 /// method.)
277251 #[ inline]
278252 pub fn look_for_viewport_percentages ( & mut self ) {
279- self . tokenizer . look_for_viewport_percentages ( )
253+ ( self . tokenizer . 0 ) . look_for_viewport_percentages ( )
280254 }
281255
282256 /// Return whether a `vh`, `vw`, `vmin`, or `vmax` dimension has been seen by the tokenizer
283257 /// since `look_for_viewport_percentages` was called, and stop looking.
284258 #[ inline]
285259 pub fn seen_viewport_percentages ( & mut self ) -> bool {
286- self . tokenizer . seen_viewport_percentages ( )
260+ ( self . tokenizer . 0 ) . seen_viewport_percentages ( )
287261 }
288262
289263 /// Execute the given closure, passing it the parser.
@@ -304,25 +278,25 @@ impl<'i, 't> Parser<'i, 't> {
304278 /// Return a slice of the CSS input
305279 #[ inline]
306280 pub fn slice ( & self , range : Range < SourcePosition > ) -> & ' i str {
307- self . tokenizer . slice ( range. start . position ..range. end . position )
281+ ( self . tokenizer . 0 ) . slice ( range. start . position ..range. end . position )
308282 }
309283
310284 /// Return a slice of the CSS input, from the given position to the current one.
311285 #[ inline]
312286 pub fn slice_from ( & self , start_position : SourcePosition ) -> & ' i str {
313- self . tokenizer . slice_from ( start_position. position )
287+ ( self . tokenizer . 0 ) . slice_from ( start_position. position )
314288 }
315289
316290 /// Return the line and column number within the input for the current position.
317291 #[ inline]
318292 pub fn current_source_location ( & self ) -> SourceLocation {
319- self . tokenizer . current_source_location ( )
293+ ( self . tokenizer . 0 ) . current_source_location ( )
320294 }
321295
322296 /// Return the line and column number within the input for the given position.
323297 #[ inline]
324298 pub fn source_location ( & self , target : SourcePosition ) -> SourceLocation {
325- self . tokenizer . source_location ( target. position )
299+ ( self . tokenizer . 0 ) . source_location ( target. position )
326300 }
327301
328302 /// Return the next token in the input that is neither whitespace or a comment,
@@ -363,13 +337,13 @@ impl<'i, 't> Parser<'i, 't> {
363337 /// comments should always be ignored between tokens.
364338 pub fn next_including_whitespace_and_comments ( & mut self ) -> Result < Token < ' i > , BasicParseError < ' i > > {
365339 if let Some ( block_type) = self . at_start_of . take ( ) {
366- consume_until_end_of_block ( block_type, & mut * self . tokenizer ) ;
340+ consume_until_end_of_block ( block_type, & mut self . tokenizer . 0 ) ;
367341 }
368- let byte = self . tokenizer . next_byte ( ) ;
342+ let byte = ( self . tokenizer . 0 ) . next_byte ( ) ;
369343 if self . stop_before . contains ( Delimiters :: from_byte ( byte) ) {
370344 return Err ( BasicParseError :: EndOfInput )
371345 }
372- let token = try!( self . tokenizer . next ( ) . map_err ( |( ) | BasicParseError :: EndOfInput ) ) ;
346+ let token = try!( ( self . tokenizer . 0 ) . next ( ) . map_err ( |( ) | BasicParseError :: EndOfInput ) ) ;
373347 if let Some ( block_type) = BlockType :: opening ( & token) {
374348 self . at_start_of = Some ( block_type) ;
375349 }
@@ -400,10 +374,10 @@ impl<'i, 't> Parser<'i, 't> {
400374 /// or if a closure call leaves some input before the next comma or the end of the input.
401375 #[ inline]
402376 pub fn parse_comma_separated < F , T , E > ( & mut self , mut parse_one : F ) -> Result < Vec < T > , ParseError < ' i , E > >
403- where F : for < ' ii , ' tt > FnMut ( & mut Parser < ' ii , ' tt > ) -> Result < T , ParseError < ' ii , E > > {
377+ where F : for < ' tt > FnMut ( & mut Parser < ' i , ' tt > ) -> Result < T , ParseError < ' i , E > > {
404378 let mut values = vec ! [ ] ;
405379 loop {
406- values. push ( try!( self . parse_until_before ( Delimiter :: Comma , |parser| parse_one ( parser ) ) ) ) ;
380+ values. push ( try!( self . parse_until_before ( Delimiter :: Comma , & mut parse_one) ) ) ;
407381 match self . next ( ) {
408382 Err ( _) => return Ok ( values) ,
409383 Ok ( Token :: Comma ) => continue ,
@@ -426,31 +400,7 @@ impl<'i, 't> Parser<'i, 't> {
426400 #[ inline]
427401 pub fn parse_nested_block < F , T , E > ( & mut self , parse : F ) -> Result < T , ParseError < ' i , E > >
428402 where F : for < ' tt > FnOnce ( & mut Parser < ' i , ' tt > ) -> Result < T , ParseError < ' i , E > > {
429- let block_type = self . at_start_of . take ( ) . expect ( "\
430- A nested parser can only be created when a Function, \
431- ParenthesisBlock, SquareBracketBlock, or CurlyBracketBlock \
432- token was just consumed.\
433- ") ;
434- let closing_delimiter = match block_type {
435- BlockType :: CurlyBracket => ClosingDelimiter :: CloseCurlyBracket ,
436- BlockType :: SquareBracket => ClosingDelimiter :: CloseSquareBracket ,
437- BlockType :: Parenthesis => ClosingDelimiter :: CloseParenthesis ,
438- } ;
439- let result;
440- // Introduce a new scope to limit duration of nested_parser’s borrow
441- {
442- let mut nested_parser = Parser {
443- tokenizer : MaybeOwned :: Borrowed ( & mut * self . tokenizer ) ,
444- at_start_of : None ,
445- stop_before : closing_delimiter,
446- } ;
447- result = nested_parser. parse_entirely ( parse) ;
448- if let Some ( block_type) = nested_parser. at_start_of {
449- consume_until_end_of_block ( block_type, & mut * nested_parser. tokenizer ) ;
450- }
451- }
452- consume_until_end_of_block ( block_type, & mut * self . tokenizer ) ;
453- result
403+ parse_nested_block ( self , parse)
454404 }
455405
456406 /// Limit parsing to until a given delimiter. (E.g. a semicolon for a property value.)
@@ -464,34 +414,7 @@ impl<'i, 't> Parser<'i, 't> {
464414 pub fn parse_until_before < F , T , E > ( & mut self , delimiters : Delimiters , parse : F )
465415 -> Result < T , ParseError < ' i , E > >
466416 where F : for < ' tt > FnOnce ( & mut Parser < ' i , ' tt > ) -> Result < T , ParseError < ' i , E > > {
467- let delimiters = self . stop_before | delimiters;
468- let result;
469- // Introduce a new scope to limit duration of nested_parser’s borrow
470- {
471- let mut delimited_parser = Parser {
472- tokenizer : MaybeOwned :: Borrowed ( & mut * self . tokenizer ) ,
473- at_start_of : self . at_start_of . take ( ) ,
474- stop_before : delimiters,
475- } ;
476- result = delimited_parser. parse_entirely ( parse) ;
477- if let Some ( block_type) = delimited_parser. at_start_of {
478- consume_until_end_of_block ( block_type, & mut * delimited_parser. tokenizer ) ;
479- }
480- }
481- // FIXME: have a special-purpose tokenizer method for this that does less work.
482- loop {
483- if delimiters. contains ( Delimiters :: from_byte ( self . tokenizer . next_byte ( ) ) ) {
484- break
485- }
486- if let Ok ( token) = self . tokenizer . next ( ) {
487- if let Some ( block_type) = BlockType :: opening ( & token) {
488- consume_until_end_of_block ( block_type, & mut * self . tokenizer ) ;
489- }
490- } else {
491- break
492- }
493- }
494- result
417+ parse_until_before ( self , delimiters, parse)
495418 }
496419
497420 /// Like `parse_until_before`, but also consume the delimiter token.
@@ -727,6 +650,87 @@ impl<'i, 't> Parser<'i, 't> {
727650 }
728651}
729652
653+ pub fn parse_until_before < ' i : ' t , ' t , F , T , E > ( parser : & mut Parser < ' i , ' t > ,
654+ delimiters : Delimiters ,
655+ parse : F )
656+ -> Result < T , ParseError < ' i , E > >
657+ where F : for < ' tt > FnOnce ( & mut Parser < ' i , ' tt > ) -> Result < T , ParseError < ' i , E > > {
658+ let delimiters = parser. stop_before | delimiters;
659+ let result;
660+ // Introduce a new scope to limit duration of nested_parser’s borrow
661+ {
662+ let mut delimited_parser = Parser {
663+ tokenizer : parser. tokenizer ,
664+ at_start_of : parser. at_start_of . take ( ) ,
665+ stop_before : delimiters,
666+ } ;
667+ result = delimited_parser. parse_entirely ( parse) ;
668+ if let Some ( block_type) = delimited_parser. at_start_of {
669+ consume_until_end_of_block ( block_type, & mut delimited_parser. tokenizer . 0 ) ;
670+ }
671+ }
672+ // FIXME: have a special-purpose tokenizer method for this that does less work.
673+ loop {
674+ if delimiters. contains ( Delimiters :: from_byte ( ( parser. tokenizer . 0 ) . next_byte ( ) ) ) {
675+ break
676+ }
677+ if let Ok ( token) = ( parser. tokenizer . 0 ) . next ( ) {
678+ if let Some ( block_type) = BlockType :: opening ( & token) {
679+ consume_until_end_of_block ( block_type, & mut parser. tokenizer . 0 ) ;
680+ }
681+ } else {
682+ break
683+ }
684+ }
685+ result
686+ }
687+
688+ pub fn parse_until_after < ' i : ' t , ' t , F , T , E > ( parser : & mut Parser < ' i , ' t > ,
689+ delimiters : Delimiters ,
690+ parse : F )
691+ -> Result < T , ParseError < ' i , E > >
692+ where F : for < ' tt > FnOnce ( & mut Parser < ' i , ' tt > ) -> Result < T , ParseError < ' i , E > > {
693+ let result = parser. parse_until_before ( delimiters, parse) ;
694+ let next_byte = ( parser. tokenizer . 0 ) . next_byte ( ) ;
695+ if next_byte. is_some ( ) && !parser. stop_before . contains ( Delimiters :: from_byte ( next_byte) ) {
696+ debug_assert ! ( delimiters. contains( Delimiters :: from_byte( next_byte) ) ) ;
697+ ( parser. tokenizer . 0 ) . advance ( 1 ) ;
698+ if next_byte == Some ( b'{' ) {
699+ consume_until_end_of_block ( BlockType :: CurlyBracket , & mut parser. tokenizer . 0 ) ;
700+ }
701+ }
702+ result
703+ }
704+
705+ pub fn parse_nested_block < ' i : ' t , ' t , F , T , E > ( parser : & mut Parser < ' i , ' t > , parse : F )
706+ -> Result < T , ParseError < ' i , E > >
707+ where F : for < ' tt > FnOnce ( & mut Parser < ' i , ' tt > ) -> Result < T , ParseError < ' i , E > > {
708+ let block_type = parser. at_start_of . take ( ) . expect ( "\
709+ A nested parser can only be created when a Function, \
710+ ParenthesisBlock, SquareBracketBlock, or CurlyBracketBlock \
711+ token was just consumed.\
712+ ") ;
713+ let closing_delimiter = match block_type {
714+ BlockType :: CurlyBracket => ClosingDelimiter :: CloseCurlyBracket ,
715+ BlockType :: SquareBracket => ClosingDelimiter :: CloseSquareBracket ,
716+ BlockType :: Parenthesis => ClosingDelimiter :: CloseParenthesis ,
717+ } ;
718+ let result;
719+ // Introduce a new scope to limit duration of nested_parser’s borrow
720+ {
721+ let mut nested_parser = Parser {
722+ tokenizer : parser. tokenizer ,
723+ at_start_of : None ,
724+ stop_before : closing_delimiter,
725+ } ;
726+ result = nested_parser. parse_entirely ( parse) ;
727+ if let Some ( block_type) = nested_parser. at_start_of {
728+ consume_until_end_of_block ( block_type, & mut nested_parser. tokenizer . 0 ) ;
729+ }
730+ }
731+ consume_until_end_of_block ( block_type, & mut parser. tokenizer . 0 ) ;
732+ result
733+ }
730734
731735fn consume_until_end_of_block ( block_type : BlockType , tokenizer : & mut Tokenizer ) {
732736 let mut stack = vec ! [ block_type] ;
@@ -747,20 +751,3 @@ fn consume_until_end_of_block(block_type: BlockType, tokenizer: &mut Tokenizer)
747751 }
748752 }
749753}
750-
751- pub fn parse_until_after < ' i , ' t , F , T , E > ( parser : & mut Parser < ' i , ' t > ,
752- delimiters : Delimiters ,
753- parse : F )
754- -> Result < T , ParseError < ' i , E > >
755- where F : for < ' tt > FnOnce ( & mut Parser < ' i , ' tt > ) -> Result < T , ParseError < ' i , E > > {
756- let result = parser. parse_until_before ( delimiters, parse) ;
757- let next_byte = parser. tokenizer . next_byte ( ) ;
758- if next_byte. is_some ( ) && !parser. stop_before . contains ( Delimiters :: from_byte ( next_byte) ) {
759- debug_assert ! ( delimiters. contains( Delimiters :: from_byte( next_byte) ) ) ;
760- parser. tokenizer . advance ( 1 ) ;
761- if next_byte == Some ( b'{' ) {
762- consume_until_end_of_block ( BlockType :: CurlyBracket , & mut * parser. tokenizer ) ;
763- }
764- }
765- result
766- }
0 commit comments