@@ -61,46 +61,35 @@ impl<'a, T> ParseError<'a, T> {
61
61
}
62
62
}
63
63
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 ;
64
+ /// The owned input for a parser.
65
+ pub struct ParserInput < ' t > ( Tokenizer < ' t > ) ;
73
66
74
- fn deref < ' b > ( & ' b self ) -> & ' b T {
75
- match * self {
76
- MaybeOwned :: Owned ( ref t) => t,
77
- MaybeOwned :: Borrowed ( ref pointer) => & * * pointer,
78
- }
67
+ impl < ' t > ParserInput < ' t > {
68
+ /// Create a new input for a parser.
69
+ pub fn new ( input : & ' t str ) -> ParserInput < ' t > {
70
+ ParserInput ( Tokenizer :: new ( input) )
79
71
}
80
72
}
81
73
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
- }
74
+ impl < ' t > ops:: Deref for ParserInput < ' t > {
75
+ type Target = Tokenizer < ' t > ;
76
+
77
+ fn deref ( & self ) -> & Tokenizer < ' t > {
78
+ & self . 0
88
79
}
89
80
}
90
81
91
- impl < ' a , T > Clone for MaybeOwned < ' a , T > where T : Clone {
92
- fn clone ( & self ) -> MaybeOwned < ' a , T > {
93
- MaybeOwned :: Owned ( ( * * self ) . clone ( ) )
82
+ impl < ' t > ops :: DerefMut for ParserInput < ' t > {
83
+ fn deref_mut ( & mut self ) -> & mut Tokenizer < ' t > {
84
+ & mut self . 0
94
85
}
95
86
}
96
87
97
-
98
88
/// A CSS parser that borrows its `&str` input,
99
89
/// yields `Token`s,
100
90
/// and keeps track of nested blocks and functions.
101
- #[ derive( Clone ) ]
102
91
pub struct Parser < ' i : ' t , ' t > {
103
- tokenizer : MaybeOwned < ' t , Tokenizer < ' i > > ,
92
+ tokenizer : & ' t mut ParserInput < ' i > ,
104
93
/// If `Some(_)`, .parse_nested_block() can be called.
105
94
at_start_of : Option < BlockType > ,
106
95
/// For parsers from `parse_until` or `parse_nested_block`
@@ -203,12 +192,12 @@ impl Delimiters {
203
192
}
204
193
}
205
194
206
- impl < ' i , ' t > Parser < ' i , ' t > {
195
+ impl < ' i : ' t , ' t > Parser < ' i , ' t > {
207
196
/// Create a new parser
208
197
#[ inline]
209
- pub fn new ( input : & ' i str ) -> Parser < ' i , ' i > {
198
+ pub fn new ( input : & ' t mut ParserInput < ' i > ) -> Parser < ' i , ' t > {
210
199
Parser {
211
- tokenizer : MaybeOwned :: Owned ( Tokenizer :: new ( input) ) ,
200
+ tokenizer : input,
212
201
at_start_of : None ,
213
202
stop_before : Delimiter :: None ,
214
203
}
@@ -400,10 +389,10 @@ impl<'i, 't> Parser<'i, 't> {
400
389
/// or if a closure call leaves some input before the next comma or the end of the input.
401
390
#[ inline]
402
391
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 > > {
392
+ where F : for < ' tt > FnMut ( & mut Parser < ' i , ' tt > ) -> Result < T , ParseError < ' i , E > > {
404
393
let mut values = vec ! [ ] ;
405
394
loop {
406
- values. push ( try!( self . parse_until_before ( Delimiter :: Comma , |parser| parse_one ( parser ) ) ) ) ;
395
+ values. push ( try!( self . parse_until_before ( Delimiter :: Comma , & mut parse_one) ) ) ;
407
396
match self . next ( ) {
408
397
Err ( _) => return Ok ( values) ,
409
398
Ok ( Token :: Comma ) => continue ,
@@ -426,31 +415,7 @@ impl<'i, 't> Parser<'i, 't> {
426
415
#[ inline]
427
416
pub fn parse_nested_block < F , T , E > ( & mut self , parse : F ) -> Result < T , ParseError < ' i , E > >
428
417
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
418
+ parse_nested_block ( self , parse)
454
419
}
455
420
456
421
/// Limit parsing to until a given delimiter. (E.g. a semicolon for a property value.)
@@ -463,35 +428,8 @@ impl<'i, 't> Parser<'i, 't> {
463
428
#[ inline]
464
429
pub fn parse_until_before < F , T , E > ( & mut self , delimiters : Delimiters , parse : F )
465
430
-> Result < T , ParseError < ' i , E > >
466
- where F : for <' ii , ' tt > FnOnce ( & mut Parser < ' ii , ' tt > ) -> Result < T , ParseError < ' ii , 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
431
+ where F : for < ' tt > FnOnce ( & mut Parser < ' i , ' tt > ) -> Result < T , ParseError < ' i , E > > {
432
+ parse_until_before ( self , delimiters, parse)
495
433
}
496
434
497
435
/// Like `parse_until_before`, but also consume the delimiter token.
@@ -502,17 +440,8 @@ impl<'i, 't> Parser<'i, 't> {
502
440
#[ inline]
503
441
pub fn parse_until_after < F , T , E > ( & mut self , delimiters : Delimiters , parse : F )
504
442
-> Result < T , ParseError < ' i , E > >
505
- where F : for <' ii , ' tt > FnOnce ( & mut Parser < ' ii , ' tt > ) -> Result < T , ParseError < ' ii , E > > {
506
- let result = self . parse_until_before ( delimiters, parse) ;
507
- let next_byte = self . tokenizer . next_byte ( ) ;
508
- if next_byte. is_some ( ) && !self . stop_before . contains ( Delimiters :: from_byte ( next_byte) ) {
509
- debug_assert ! ( delimiters. contains( Delimiters :: from_byte( next_byte) ) ) ;
510
- self . tokenizer . advance ( 1 ) ;
511
- if next_byte == Some ( b'{' ) {
512
- consume_until_end_of_block ( BlockType :: CurlyBracket , & mut * self . tokenizer ) ;
513
- }
514
- }
515
- result
443
+ where F : for < ' tt > FnOnce ( & mut Parser < ' i , ' tt > ) -> Result < T , ParseError < ' i , E > > {
444
+ parse_until_after ( self , delimiters, parse)
516
445
}
517
446
518
447
/// Parse a <whitespace-token> and return its value.
@@ -736,6 +665,87 @@ impl<'i, 't> Parser<'i, 't> {
736
665
}
737
666
}
738
667
668
+ pub fn parse_until_before < ' i : ' t , ' t , F , T , E > ( parser : & mut Parser < ' i , ' t > ,
669
+ delimiters : Delimiters ,
670
+ parse : F )
671
+ -> Result < T , ParseError < ' i , E > >
672
+ where F : for < ' tt > FnOnce ( & mut Parser < ' i , ' tt > ) -> Result < T , ParseError < ' i , E > > {
673
+ let delimiters = parser. stop_before | delimiters;
674
+ let result;
675
+ // Introduce a new scope to limit duration of nested_parser’s borrow
676
+ {
677
+ let mut delimited_parser = Parser {
678
+ tokenizer : parser. tokenizer ,
679
+ at_start_of : parser. at_start_of . take ( ) ,
680
+ stop_before : delimiters,
681
+ } ;
682
+ result = delimited_parser. parse_entirely ( parse) ;
683
+ if let Some ( block_type) = delimited_parser. at_start_of {
684
+ consume_until_end_of_block ( block_type, & mut * delimited_parser. tokenizer ) ;
685
+ }
686
+ }
687
+ // FIXME: have a special-purpose tokenizer method for this that does less work.
688
+ loop {
689
+ if delimiters. contains ( Delimiters :: from_byte ( parser. tokenizer . next_byte ( ) ) ) {
690
+ break
691
+ }
692
+ if let Ok ( token) = parser. tokenizer . next ( ) {
693
+ if let Some ( block_type) = BlockType :: opening ( & token) {
694
+ consume_until_end_of_block ( block_type, & mut * parser. tokenizer ) ;
695
+ }
696
+ } else {
697
+ break
698
+ }
699
+ }
700
+ result
701
+ }
702
+
703
+ pub fn parse_until_after < ' i : ' t , ' t , F , T , E > ( parser : & mut Parser < ' i , ' t > ,
704
+ delimiters : Delimiters ,
705
+ 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 result = parser. parse_until_before ( delimiters, parse) ;
709
+ let next_byte = parser. tokenizer . next_byte ( ) ;
710
+ if next_byte. is_some ( ) && !parser. stop_before . contains ( Delimiters :: from_byte ( next_byte) ) {
711
+ debug_assert ! ( delimiters. contains( Delimiters :: from_byte( next_byte) ) ) ;
712
+ parser. tokenizer . advance ( 1 ) ;
713
+ if next_byte == Some ( b'{' ) {
714
+ consume_until_end_of_block ( BlockType :: CurlyBracket , & mut * parser. tokenizer ) ;
715
+ }
716
+ }
717
+ result
718
+ }
719
+
720
+ pub fn parse_nested_block < ' i : ' t , ' t , F , T , E > ( parser : & mut Parser < ' i , ' t > , parse : F )
721
+ -> Result < T , ParseError < ' i , E > >
722
+ where F : for < ' tt > FnOnce ( & mut Parser < ' i , ' tt > ) -> Result < T , ParseError < ' i , E > > {
723
+ let block_type = parser. at_start_of . take ( ) . expect ( "\
724
+ A nested parser can only be created when a Function, \
725
+ ParenthesisBlock, SquareBracketBlock, or CurlyBracketBlock \
726
+ token was just consumed.\
727
+ ") ;
728
+ let closing_delimiter = match block_type {
729
+ BlockType :: CurlyBracket => ClosingDelimiter :: CloseCurlyBracket ,
730
+ BlockType :: SquareBracket => ClosingDelimiter :: CloseSquareBracket ,
731
+ BlockType :: Parenthesis => ClosingDelimiter :: CloseParenthesis ,
732
+ } ;
733
+ let result;
734
+ // Introduce a new scope to limit duration of nested_parser’s borrow
735
+ {
736
+ let mut nested_parser = Parser {
737
+ tokenizer : parser. tokenizer ,
738
+ at_start_of : None ,
739
+ stop_before : closing_delimiter,
740
+ } ;
741
+ result = nested_parser. parse_entirely ( parse) ;
742
+ if let Some ( block_type) = nested_parser. at_start_of {
743
+ consume_until_end_of_block ( block_type, & mut * nested_parser. tokenizer ) ;
744
+ }
745
+ }
746
+ consume_until_end_of_block ( block_type, & mut * parser. tokenizer ) ;
747
+ result
748
+ }
739
749
740
750
fn consume_until_end_of_block ( block_type : BlockType , tokenizer : & mut Tokenizer ) {
741
751
let mut stack = vec ! [ block_type] ;
0 commit comments