| 1 | use core::fmt; |
| 2 | |
| 3 | /// Alternative implementation of `fmt::Debug` for byte slice. |
| 4 | /// |
| 5 | /// Standard `Debug` implementation for `[u8]` is comma separated |
| 6 | /// list of numbers. Since large amount of byte strings are in fact |
| 7 | /// ASCII strings or contain a lot of ASCII strings (e. g. HTTP), |
| 8 | /// it is convenient to print strings as ASCII when possible. |
| 9 | /// |
| 10 | /// This struct wraps `&[u8]` just to override `fmt::Debug`. |
| 11 | /// |
| 12 | /// `BsDebug` is not a part of public API of bytes crate. |
| 13 | pub(crate) struct BsDebug<'a>(pub(crate) &'a [u8]); |
| 14 | |
| 15 | impl fmt::Debug for BsDebug<'_> { |
| 16 | fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> { |
| 17 | write!(fmt, "b \"" )?; |
| 18 | for &c in self.0 { |
| 19 | // https://doc.rust-lang.org/reference.html#byte-escapes |
| 20 | if c == b' \n' { |
| 21 | write!(fmt, " \\n" )?; |
| 22 | } else if c == b' \r' { |
| 23 | write!(fmt, " \\r" )?; |
| 24 | } else if c == b' \t' { |
| 25 | write!(fmt, " \\t" )?; |
| 26 | } else if c == b' \\' || c == b'"' { |
| 27 | write!(fmt, " \\{}" , c as char)?; |
| 28 | } else if c == b' \0' { |
| 29 | write!(fmt, " \\0" )?; |
| 30 | // ASCII printable |
| 31 | } else if (0x20..0x7f).contains(&c) { |
| 32 | write!(fmt, " {}" , c as char)?; |
| 33 | } else { |
| 34 | write!(fmt, " \\x {:02x}" , c)?; |
| 35 | } |
| 36 | } |
| 37 | write!(fmt, " \"" )?; |
| 38 | Ok(()) |
| 39 | } |
| 40 | } |
| 41 | |
| 42 | #[cfg (test)] |
| 43 | mod tests { |
| 44 | use std::format; |
| 45 | use std::prelude::v1::*; |
| 46 | |
| 47 | use super::BsDebug; |
| 48 | |
| 49 | #[test ] |
| 50 | fn debug() { |
| 51 | let vec: Vec<_> = (0..0x100).map(|b| b as u8).collect(); |
| 52 | |
| 53 | let expected = "b \"\ |
| 54 | \\0 \\x01 \\x02 \\x03 \\x04 \\x05 \\x06 \\x07\ |
| 55 | \\x08 \\t \\n \\x0b \\x0c \\r \\x0e \\x0f\ |
| 56 | \\x10 \\x11 \\x12 \\x13 \\x14 \\x15 \\x16 \\x17\ |
| 57 | \\x18 \\x19 \\x1a \\x1b \\x1c \\x1d \\x1e \\x1f\ |
| 58 | \x20! \\\"#$%&'()*+,-./0123456789:;<=>?\ |
| 59 | @ABCDEFGHIJKLMNOPQRSTUVWXYZ[ \\\\]^_\ |
| 60 | `abcdefghijklmnopqrstuvwxyz{|}~ \\x7f\ |
| 61 | \\x80 \\x81 \\x82 \\x83 \\x84 \\x85 \\x86 \\x87\ |
| 62 | \\x88 \\x89 \\x8a \\x8b \\x8c \\x8d \\x8e \\x8f\ |
| 63 | \\x90 \\x91 \\x92 \\x93 \\x94 \\x95 \\x96 \\x97\ |
| 64 | \\x98 \\x99 \\x9a \\x9b \\x9c \\x9d \\x9e \\x9f\ |
| 65 | \\xa0 \\xa1 \\xa2 \\xa3 \\xa4 \\xa5 \\xa6 \\xa7\ |
| 66 | \\xa8 \\xa9 \\xaa \\xab \\xac \\xad \\xae \\xaf\ |
| 67 | \\xb0 \\xb1 \\xb2 \\xb3 \\xb4 \\xb5 \\xb6 \\xb7\ |
| 68 | \\xb8 \\xb9 \\xba \\xbb \\xbc \\xbd \\xbe \\xbf\ |
| 69 | \\xc0 \\xc1 \\xc2 \\xc3 \\xc4 \\xc5 \\xc6 \\xc7\ |
| 70 | \\xc8 \\xc9 \\xca \\xcb \\xcc \\xcd \\xce \\xcf\ |
| 71 | \\xd0 \\xd1 \\xd2 \\xd3 \\xd4 \\xd5 \\xd6 \\xd7\ |
| 72 | \\xd8 \\xd9 \\xda \\xdb \\xdc \\xdd \\xde \\xdf\ |
| 73 | \\xe0 \\xe1 \\xe2 \\xe3 \\xe4 \\xe5 \\xe6 \\xe7\ |
| 74 | \\xe8 \\xe9 \\xea \\xeb \\xec \\xed \\xee \\xef\ |
| 75 | \\xf0 \\xf1 \\xf2 \\xf3 \\xf4 \\xf5 \\xf6 \\xf7\ |
| 76 | \\xf8 \\xf9 \\xfa \\xfb \\xfc \\xfd \\xfe \\xff \"" ; |
| 77 | |
| 78 | assert_eq!(expected, format!("{:?}" , BsDebug(&vec))); |
| 79 | } |
| 80 | } |
| 81 | |