@@ -142,19 +142,36 @@ pub enum Alignment {
142142#[ derive( Copy , Clone , Debug , PartialEq ) ]
143143pub enum Flag {
144144 /// A `+` will be used to denote positive numbers.
145- FlagSignPlus ,
145+ FlagSignPlus = 0b0000_0001 ,
146146 /// A `-` will be used to denote negative numbers. This is the default.
147- FlagSignMinus ,
147+ FlagSignMinus = 0b0000_0010 ,
148148 /// An alternate form will be used for the value. In the case of numbers,
149149 /// this means that the number will be prefixed with the supplied string.
150- FlagAlternate ,
150+ FlagAlternate = 0b0000_0100 ,
151151 /// For numbers, this means that the number will be padded with zeroes,
152152 /// and the sign (`+` or `-`) will precede them.
153- FlagSignAwareZeroPad ,
154- /// For Debug / `?`, format integers in lower-case hexadecimal.
155- FlagDebugLowerHex ,
156- /// For Debug / `?`, format integers in upper-case hexadecimal.
157- FlagDebugUpperHex ,
153+ FlagSignAwareZeroPad = 0b0000_1000 ,
154+ /// For Debug / `?`, the variant used.
155+ FlagDebugVariant = 0b1111_0000_0000 ,
156+ }
157+
158+ /// Version of `DebugVariant` that can be used on stable.
159+ #[ derive( Copy , Clone , Debug , PartialEq ) ]
160+ pub enum DebugVariant {
161+ /// [`LowerHex`]-like formatting. (`{:x?}`)
162+ LowerHex = 0b0001_0000_0000 ,
163+ /// [`UpperHex`]-like formatting. (`{:X?}`)
164+ UpperHex = 0b0010_0000_0000 ,
165+ /// [`Octal`]-like formatting. (`{:o?}`)
166+ Octal = 0b0100_0000_0000 ,
167+ /// [`Binary`]-like formatting. (`{:b?}`)
168+ Binary = 0b1000_0000_0000 ,
169+ /// [`LowerExp`]-like formatting. (`{:e?}`)
170+ LowerExp = 0b0011_0000_0000 ,
171+ /// [`UpperExp`]-like formatting. (`{:E?}`)
172+ UpperExp = 0b0110_0000_0000 ,
173+ /// [`Pointer`]-like formatting. (`{:p?}`)
174+ Pointer = 0b1100_0000_0000 ,
158175}
159176
160177/// A count is used for the precision and width parameters of an integer, and
@@ -580,13 +597,13 @@ impl<'a> Parser<'a> {
580597 }
581598 // Sign flags
582599 if self . consume ( '+' ) {
583- spec. flags |= 1 << ( FlagSignPlus as u32 ) ;
600+ spec. flags |= FlagSignPlus as u32 ;
584601 } else if self . consume ( '-' ) {
585- spec. flags |= 1 << ( FlagSignMinus as u32 ) ;
602+ spec. flags |= FlagSignMinus as u32 ;
586603 }
587604 // Alternate marker
588605 if self . consume ( '#' ) {
589- spec. flags |= 1 << ( FlagAlternate as u32 ) ;
606+ spec. flags |= FlagAlternate as u32 ;
590607 }
591608 // Width and precision
592609 let mut havewidth = false ;
@@ -601,7 +618,7 @@ impl<'a> Parser<'a> {
601618 spec. width_span = Some ( self . span ( end - 1 , end + 1 ) ) ;
602619 havewidth = true ;
603620 } else {
604- spec. flags |= 1 << ( FlagSignAwareZeroPad as u32 ) ;
621+ spec. flags |= FlagSignAwareZeroPad as u32 ;
605622 }
606623 }
607624
@@ -628,31 +645,43 @@ impl<'a> Parser<'a> {
628645 spec. precision_span = Some ( self . span ( start, end) ) ;
629646 }
630647
631- let ty_span_start = self . current_pos ( ) ;
648+ let mut ty_span_start = self . cur . peek ( ) . map ( | ( pos , _ ) | * pos ) ;
632649 // Optional radix followed by the actual format specifier
633- if self . consume ( 'x' ) {
634- if self . consume ( '?' ) {
635- spec. flags |= 1 << ( FlagDebugLowerHex as u32 ) ;
636- spec. ty = "?" ;
637- } else {
638- spec. ty = "x" ;
639- }
640- } else if self . consume ( 'X' ) {
641- if self . consume ( '?' ) {
642- spec. flags |= 1 << ( FlagDebugUpperHex as u32 ) ;
643- spec. ty = "?" ;
644- } else {
645- spec. ty = "X" ;
646- }
647- } else if self . consume ( '?' ) {
650+ if self . consume ( '?' ) {
648651 spec. ty = "?" ;
649652 } else {
650653 spec. ty = self . word ( ) ;
651- if !spec. ty . is_empty ( ) {
652- let ty_span_end = self . current_pos ( ) ;
653- spec. ty_span = Some ( self . span ( ty_span_start, ty_span_end) ) ;
654+
655+ // FIXME: let chains
656+ if let Some ( & ( pos, c) ) = self . cur . peek ( ) {
657+ if c == '?' {
658+ let variant = match spec. ty {
659+ "x" => Some ( DebugVariant :: LowerHex ) ,
660+ "X" => Some ( DebugVariant :: UpperHex ) ,
661+ "o" => Some ( DebugVariant :: Octal ) ,
662+ "b" => Some ( DebugVariant :: Binary ) ,
663+ "e" => Some ( DebugVariant :: LowerExp ) ,
664+ "E" => Some ( DebugVariant :: UpperExp ) ,
665+ "p" => Some ( DebugVariant :: Pointer ) ,
666+ _ => None ,
667+ } ;
668+ if let Some ( variant) = variant {
669+ spec. ty = "?" ;
670+ spec. flags |= variant as u32 ;
671+ ty_span_start = Some ( pos) ;
672+
673+ // only advance if we have a valid variant
674+ self . cur . next ( ) ;
675+ }
676+ }
654677 }
655678 }
679+ let ty_span_end = self . cur . peek ( ) . map ( |( pos, _) | * pos) ;
680+ if !spec. ty . is_empty ( ) {
681+ spec. ty_span = ty_span_start
682+ . and_then ( |s| ty_span_end. map ( |e| ( s, e) ) )
683+ . map ( |( start, end) | self . to_span_index ( start) . to ( self . to_span_index ( end) ) ) ;
684+ }
656685 spec
657686 }
658687
0 commit comments