This can be used for integers within a larger types which implements Debug
(possibly through derive) but not fmt::UpperHex or fmt::LowerHex.
```rust
assert!(format!("{:02x?}", b"Foo\0") == "[46, 6f, 6f, 00]");
assert!(format!("{:02X?}", b"Foo\0") == "[46, 6F, 6F, 00]");
```
RFC: https://github.com/rust-lang/rfcs/pull/2226
//!
//! * *nothing* ⇒ [`Display`]
//! * `?` ⇒ [`Debug`]
//!
//! * *nothing* ⇒ [`Display`]
//! * `?` ⇒ [`Debug`]
+//! * `x?` ⇒ [`Debug`] with lower-case hexadecimal integers
+//! * `X?` ⇒ [`Debug`] with lower-case hexadecimal integers
//! * `o` ⇒ [`Octal`](trait.Octal.html)
//! * `x` ⇒ [`LowerHex`](trait.LowerHex.html)
//! * `X` ⇒ [`UpperHex`](trait.UpperHex.html)
//! * `o` ⇒ [`Octal`](trait.Octal.html)
//! * `x` ⇒ [`LowerHex`](trait.LowerHex.html)
//! * `X` ⇒ [`UpperHex`](trait.UpperHex.html)
// flags available in the v1 format of format_args
#[derive(Copy, Clone)]
// flags available in the v1 format of format_args
#[derive(Copy, Clone)]
-enum FlagV1 { SignPlus, SignMinus, Alternate, SignAwareZeroPad, }
+enum FlagV1 { SignPlus, SignMinus, Alternate, SignAwareZeroPad, DebugLowerHex, DebugUpperHex }
impl<'a> Arguments<'a> {
/// When using the format_args!() macro, this function is used to generate the
impl<'a> Arguments<'a> {
/// When using the format_args!() macro, this function is used to generate the
self.flags & (1 << FlagV1::SignAwareZeroPad as u32) != 0
}
self.flags & (1 << FlagV1::SignAwareZeroPad as u32) != 0
}
+ // FIXME: Decide what public API we want for these two flags.
+ // https://github.com/rust-lang/rust/issues/48584
+ fn debug_lower_hex(&self) -> bool { self.flags & (1 << FlagV1::DebugLowerHex as u32) != 0 }
+
+ fn debug_upper_hex(&self) -> bool { self.flags & (1 << FlagV1::DebugUpperHex as u32) != 0 }
+
/// Creates a [`DebugStruct`] builder designed to assist with creation of
/// [`fmt::Debug`] implementations for structs.
///
/// Creates a [`DebugStruct`] builder designed to assist with creation of
/// [`fmt::Debug`] implementations for structs.
///
impl fmt::Debug for $T {
#[inline]
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
impl fmt::Debug for $T {
#[inline]
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- fmt::Display::fmt(self, f)
+ if f.debug_lower_hex() {
+ fmt::LowerHex::fmt(self, f)
+ } else if f.debug_upper_hex() {
+ fmt::UpperHex::fmt(self, f)
+ } else {
+ fmt::Display::fmt(self, f)
+ }
assert!(format!("{}", i32::MIN) == "-2147483648");
assert!(format!("{}", i64::MIN) == "-9223372036854775808");
}
assert!(format!("{}", i32::MIN) == "-2147483648");
assert!(format!("{}", i64::MIN) == "-9223372036854775808");
}
+
+#[test]
+fn test_format_debug_hex() {
+ assert!(format!("{:02x?}", b"Foo\0") == "[46, 6f, 6f, 00]");
+ assert!(format!("{:02X?}", b"Foo\0") == "[46, 6F, 6F, 00]");
+}
/// For numbers, this means that the number will be padded with zeroes,
/// and the sign (`+` or `-`) will precede them.
FlagSignAwareZeroPad,
/// For numbers, this means that the number will be padded with zeroes,
/// and the sign (`+` or `-`) will precede them.
FlagSignAwareZeroPad,
+ /// For Debug / `?`, format integers in lower-case hexadecimal.
+ FlagDebugLowerHex,
+ /// For Debug / `?`, format integers in upper-case hexadecimal.
+ FlagDebugUpperHex,
}
/// A count is used for the precision and width parameters of an integer, and
}
/// A count is used for the precision and width parameters of an integer, and
spec.precision = self.count();
}
}
spec.precision = self.count();
}
}
- // Finally the actual format specifier
- if self.consume('?') {
+ // Optional radix followed by the actual format specifier
+ if self.consume('x') {
+ if self.consume('?') {
+ spec.flags |= 1 << (FlagDebugLowerHex as u32);
+ spec.ty = "?";
+ } else {
+ spec.ty = "x";
+ }
+ } else if self.consume('X') {
+ if self.consume('?') {
+ spec.flags |= 1 << (FlagDebugUpperHex as u32);
+ spec.ty = "?";
+ } else {
+ spec.ty = "X";
+ }
+ } else if self.consume('?') {
spec.ty = "?";
} else {
spec.ty = self.word();
spec.ty = "?";
} else {
spec.ty = self.word();