@@ -767,44 +767,97 @@ macro_rules! impl_choice_for_tuple {
767767 impl_choice_for_tuple!( $( $X) * ) ;
768768 impl_choice_for_tuple!( ~ $head $( $X) * ) ;
769769 } ;
770- ( ~ $( $X: ident) * ) => {
770+ ( ~ $Head : ident $ ( $X: ident) + ) => {
771771 #[ allow( unused_variables, non_snake_case) ]
772- impl <' a, I , E , $( $X) ,* , O > Parser <' a, I , O , E > for Choice <( $( $X, ) * ) , O >
772+ impl <' a, I , E , $Head , $ ( $X) ,* , O > Parser <' a, I , O , E > for Choice <( $Head , $( $X, ) * ) , O >
773773 where
774774 I : Input + ?Sized ,
775775 E : ParserExtra <' a, I >,
776+ $Head: Parser <' a, I , O , E >,
776777 $( $X: Parser <' a, I , O , E >) ,*
777778 {
778779 #[ inline]
779780 fn go<M : Mode >( & self , inp: & mut InputRef <' a, ' _, I , E >) -> PResult <M , O , E :: Error > {
780781 let before = inp. save( ) ;
781782
782- let Choice { parsers: ( $( $X, ) * ) , .. } = self ;
783+ let Choice { parsers: ( $Head, $( $X, ) * ) , .. } = self ;
784+
785+ let mut err = match $Head. go:: <M >( inp) {
786+ Ok ( out) => return Ok ( out) ,
787+ Err ( e) => {
788+ inp. rewind( before) ;
789+ e
790+ }
791+ } ;
783792
784- let mut err: Option <Located <E :: Error >> = None ;
785793 $(
786794 match $X. go:: <M >( inp) {
787795 Ok ( out) => return Ok ( out) ,
788796 Err ( e) => {
789797 // TODO: prioritise errors
790- err = Some ( match err {
791- Some ( err) => err. prioritize( e, |a, b| a. merge( b) ) ,
792- None => e,
793- } ) ;
798+ err = err. prioritize( e, |a, b| a. merge( b) ) ;
794799 inp. rewind( before) ;
795- } ,
800+ }
796801 }
797802 ) *
798803
799- Err ( err. unwrap_or_else( || Located :: at( inp. offset( ) . into( ) , E :: Error :: expected_found( None , None , inp. span_since( before. offset) ) ) ) )
804+ Err ( err)
805+ }
806+
807+ go_extra!( O ) ;
808+ }
809+ } ;
810+ ( ~ $Head: ident) => {
811+ impl <' a, I , E , $Head, O > Parser <' a, I , O , E > for Choice <( $Head, ) , O >
812+ where
813+ I : Input + ?Sized ,
814+ E : ParserExtra <' a, I >,
815+ $Head: Parser <' a, I , O , E >,
816+ {
817+ #[ inline]
818+ fn go<M : Mode >( & self , inp: & mut InputRef <' a, ' _, I , E >) -> PResult <M , O , E :: Error > {
819+ self . parsers. 0 . go:: <M >( inp)
800820 }
801821
802822 go_extra!( O ) ;
803823 }
804824 } ;
805825}
806826
807- impl_choice_for_tuple ! ( A_ B_ C_ D_ E_ F_ G_ H_ I_ J_ K_ L_ M_ N_ O_ P_ Q_ S_ T_ U_ V_ W_ X_ Y_ Z_ ) ;
827+ impl_choice_for_tuple ! ( A_ B_ C_ D_ E_ F_ G_ H_ I_ J_ K_ L_ M_ N_ O_ P_ Q_ R_ S_ T_ U_ V_ W_ X_ Y_ Z_ ) ;
828+
829+ impl < ' a , A , I , O , E , const N : usize > Parser < ' a , I , O , E > for Choice < [ A ; N ] , O >
830+ where
831+ A : Parser < ' a , I , O , E > ,
832+ I : Input + ?Sized ,
833+ E : ParserExtra < ' a , I > ,
834+ {
835+ fn go< M : Mode > ( & self , inp : & mut InputRef < ' a , ' _ , I , E > ) -> PResult < M , O , E :: Error > {
836+ let before = inp. save ( ) ;
837+ let res = self . parsers
838+ . iter ( )
839+ . try_fold ( None :: < Located < E :: Error > > , |err, parser, | {
840+ match parser. go :: < M > ( inp) {
841+ Ok ( out) => Err ( out) ,
842+ Err ( e) => {
843+ Ok ( Some ( match err {
844+ Some ( err) => err. prioritize( e, |a, b| a. merge( b) ) ,
845+ None => e,
846+ } ) )
847+ }
848+ }
849+ } ) ;
850+
851+ match res {
852+ Ok ( err) => Err ( err. unwrap_or_else(
853+ || Located :: at( inp. offset( ) . into( ) , E :: Error :: expected_found( None , None , inp. span_since( before. offset) ) )
854+ ) ) ,
855+ Err ( out) => Ok ( out) ,
856+ }
857+ }
858+
859+ go_extra ! ( O ) ;
860+ }
808861
809862/// See [`group`].
810863 #[ derive( Copy , Clone ) ]
0 commit comments