@@ -142,19 +142,36 @@ pub enum Alignment {
142
142
#[ derive( Copy , Clone , Debug , PartialEq ) ]
143
143
pub enum Flag {
144
144
/// A `+` will be used to denote positive numbers.
145
- FlagSignPlus ,
145
+ FlagSignPlus = 0b0000_0001 ,
146
146
/// A `-` will be used to denote negative numbers. This is the default.
147
- FlagSignMinus ,
147
+ FlagSignMinus = 0b0000_0010 ,
148
148
/// An alternate form will be used for the value. In the case of numbers,
149
149
/// this means that the number will be prefixed with the supplied string.
150
- FlagAlternate ,
150
+ FlagAlternate = 0b0000_0100 ,
151
151
/// For numbers, this means that the number will be padded with zeroes,
152
152
/// 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 ,
158
175
}
159
176
160
177
/// A count is used for the precision and width parameters of an integer, and
@@ -580,13 +597,13 @@ impl<'a> Parser<'a> {
580
597
}
581
598
// Sign flags
582
599
if self . consume ( '+' ) {
583
- spec. flags |= 1 << ( FlagSignPlus as u32 ) ;
600
+ spec. flags |= FlagSignPlus as u32 ;
584
601
} else if self . consume ( '-' ) {
585
- spec. flags |= 1 << ( FlagSignMinus as u32 ) ;
602
+ spec. flags |= FlagSignMinus as u32 ;
586
603
}
587
604
// Alternate marker
588
605
if self . consume ( '#' ) {
589
- spec. flags |= 1 << ( FlagAlternate as u32 ) ;
606
+ spec. flags |= FlagAlternate as u32 ;
590
607
}
591
608
// Width and precision
592
609
let mut havewidth = false ;
@@ -601,7 +618,7 @@ impl<'a> Parser<'a> {
601
618
spec. width_span = Some ( self . span ( end - 1 , end + 1 ) ) ;
602
619
havewidth = true ;
603
620
} else {
604
- spec. flags |= 1 << ( FlagSignAwareZeroPad as u32 ) ;
621
+ spec. flags |= FlagSignAwareZeroPad as u32 ;
605
622
}
606
623
}
607
624
@@ -628,31 +645,43 @@ impl<'a> Parser<'a> {
628
645
spec. precision_span = Some ( self . span ( start, end) ) ;
629
646
}
630
647
631
- let ty_span_start = self . current_pos ( ) ;
648
+ let mut ty_span_start = self . cur . peek ( ) . map ( | ( pos , _ ) | * pos ) ;
632
649
// 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 ( '?' ) {
648
651
spec. ty = "?" ;
649
652
} else {
650
653
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
+ }
654
677
}
655
678
}
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
+ }
656
685
spec
657
686
}
658
687
0 commit comments