@@ -639,17 +639,49 @@ impl<'i: 't, 't> Parser<'i, 't> {
639639 /// Parse a list of comma-separated values, all with the same syntax.
640640 ///
641641 /// 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.
644644 ///
645645 /// Successful results are accumulated in a vector.
646646 ///
647647 /// 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.
649650 #[ inline]
650651 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 > (
651682 & mut self ,
652683 mut parse_one : F ,
684+ ignore_errors : bool ,
653685 ) -> Result < Vec < T > , ParseError < ' i , E > >
654686 where
655687 F : for < ' tt > FnMut ( & mut Parser < ' i , ' tt > ) -> Result < T , ParseError < ' i , E > > ,
@@ -661,7 +693,11 @@ impl<'i: 't, 't> Parser<'i, 't> {
661693 let mut values = Vec :: with_capacity ( 1 ) ;
662694 loop {
663695 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+ }
665701 match self . next ( ) {
666702 Err ( _) => return Ok ( values) ,
667703 Ok ( & Token :: Comma ) => continue ,
0 commit comments