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<'a> fmt::Debug for BsDebug<'a> { |
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 super::BsDebug; |
45 | |
46 | #[test ] |
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 | |