1 use std::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 struct BsDebug<'a>(pub &'a [u8]); 14 15 impl<'a> fmt::Debug for BsDebug<'a> { fmt(&self, fmt: &mut fmt::Formatter) -> Result<(), fmt::Error>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 c >= 0x20 && c < 0x7f { 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 test { 44 use super::BsDebug; 45 46 #[test] debug()47 fn debug() { 48 let vec: Vec<_> = (0..0x100).map(|b| b as u8).collect(); 49 50 let expected = "b\"\ 51 \\0\\x01\\x02\\x03\\x04\\x05\\x06\\x07\ 52 \\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\ 53 \\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\ 54 \\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f\ 55 \x20!\\\"#$%&'()*+,-./0123456789:;<=>?\ 56 @ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\\\]^_\ 57 `abcdefghijklmnopqrstuvwxyz{|}~\\x7f\ 58 \\x80\\x81\\x82\\x83\\x84\\x85\\x86\\x87\ 59 \\x88\\x89\\x8a\\x8b\\x8c\\x8d\\x8e\\x8f\ 60 \\x90\\x91\\x92\\x93\\x94\\x95\\x96\\x97\ 61 \\x98\\x99\\x9a\\x9b\\x9c\\x9d\\x9e\\x9f\ 62 \\xa0\\xa1\\xa2\\xa3\\xa4\\xa5\\xa6\\xa7\ 63 \\xa8\\xa9\\xaa\\xab\\xac\\xad\\xae\\xaf\ 64 \\xb0\\xb1\\xb2\\xb3\\xb4\\xb5\\xb6\\xb7\ 65 \\xb8\\xb9\\xba\\xbb\\xbc\\xbd\\xbe\\xbf\ 66 \\xc0\\xc1\\xc2\\xc3\\xc4\\xc5\\xc6\\xc7\ 67 \\xc8\\xc9\\xca\\xcb\\xcc\\xcd\\xce\\xcf\ 68 \\xd0\\xd1\\xd2\\xd3\\xd4\\xd5\\xd6\\xd7\ 69 \\xd8\\xd9\\xda\\xdb\\xdc\\xdd\\xde\\xdf\ 70 \\xe0\\xe1\\xe2\\xe3\\xe4\\xe5\\xe6\\xe7\ 71 \\xe8\\xe9\\xea\\xeb\\xec\\xed\\xee\\xef\ 72 \\xf0\\xf1\\xf2\\xf3\\xf4\\xf5\\xf6\\xf7\ 73 \\xf8\\xf9\\xfa\\xfb\\xfc\\xfd\\xfe\\xff\""; 74 75 assert_eq!(expected, format!("{:?}", BsDebug(&vec))); 76 } 77 } 78