@@ -639,17 +639,49 @@ impl<'i: 't, 't> Parser<'i, 't> {
639
639
/// Parse a list of comma-separated values, all with the same syntax.
640
640
///
641
641
/// The given closure is called repeatedly with a "delimited" parser
642
- /// (see the `Parser::parse_until_before` method)
643
- /// so that it can over consume the input past a comma at this block/function nesting level.
642
+ /// (see the `Parser::parse_until_before` method) so that it can over
643
+ /// consume the input past a comma at this block/function nesting level.
644
644
///
645
645
/// Successful results are accumulated in a vector.
646
646
///
647
647
/// This method returns `Err(())` the first time that a closure call does,
648
- /// or if a closure call leaves some input before the next comma or the end of the input.
648
+ /// or if a closure call leaves some input before the next comma or the end
649
+ /// of the input.
649
650
#[ inline]
650
651
pub fn parse_comma_separated < F , T , E > (
652
+ & mut self ,
653
+ parse_one : F ,
654
+ ) -> Result < Vec < T > , ParseError < ' i , E > >
655
+ where
656
+ F : for < ' tt > FnMut ( & mut Parser < ' i , ' tt > ) -> Result < T , ParseError < ' i , E > > ,
657
+ {
658
+ self . parse_comma_separated_internal ( parse_one, /* ignore_errors = */ false )
659
+ }
660
+
661
+ /// Like `parse_comma_separated`, but ignores errors on unknown components,
662
+ /// rather than erroring out in the whole list.
663
+ ///
664
+ /// Caller must deal with the fact that the resulting list might be empty,
665
+ /// if there's no valid component on the list.
666
+ #[ inline]
667
+ pub fn parse_comma_separated_ignoring_errors < F , T , E : ' i > (
668
+ & mut self ,
669
+ parse_one : F ,
670
+ ) -> Vec < T >
671
+ where
672
+ F : for < ' tt > FnMut ( & mut Parser < ' i , ' tt > ) -> Result < T , ParseError < ' i , E > > ,
673
+ {
674
+ match self . parse_comma_separated_internal ( parse_one, /* ignore_errors = */ true ) {
675
+ Ok ( values) => values,
676
+ Err ( ..) => unreachable ! ( ) ,
677
+ }
678
+ }
679
+
680
+ #[ inline]
681
+ fn parse_comma_separated_internal < F , T , E > (
651
682
& mut self ,
652
683
mut parse_one : F ,
684
+ ignore_errors : bool ,
653
685
) -> Result < Vec < T > , ParseError < ' i , E > >
654
686
where
655
687
F : for < ' tt > FnMut ( & mut Parser < ' i , ' tt > ) -> Result < T , ParseError < ' i , E > > ,
@@ -661,7 +693,11 @@ impl<'i: 't, 't> Parser<'i, 't> {
661
693
let mut values = Vec :: with_capacity ( 1 ) ;
662
694
loop {
663
695
self . skip_whitespace ( ) ; // Unnecessary for correctness, but may help try() in parse_one rewind less.
664
- values. push ( self . parse_until_before ( Delimiter :: Comma , & mut parse_one) ?) ;
696
+ match self . parse_until_before ( Delimiter :: Comma , & mut parse_one) {
697
+ Ok ( v) => values. push ( v) ,
698
+ Err ( e) if !ignore_errors => return Err ( e) ,
699
+ Err ( _) => { } ,
700
+ }
665
701
match self . next ( ) {
666
702
Err ( _) => return Ok ( values) ,
667
703
Ok ( & Token :: Comma ) => continue ,
0 commit comments