1use core::fmt::{Debug, Formatter, Result};
2
3use super::BytesRef;
4use crate::{Bytes, BytesMut};
5
6/// Alternative implementation of `std::fmt::Debug` for byte slice.
7///
8/// Standard `Debug` implementation for `[u8]` is comma separated
9/// list of numbers. Since large amount of byte strings are in fact
10/// ASCII strings or contain a lot of ASCII strings (e. g. HTTP),
11/// it is convenient to print strings as ASCII when possible.
12impl Debug for BytesRef<'_> {
13 fn fmt(&self, f: &mut Formatter<'_>) -> Result {
14 write!(f, "b\"")?;
15 for &b in self.0 {
16 // https://doc.rust-lang.org/reference/tokens.html#byte-escapes
17 if b == b'\n' {
18 write!(f, "\\n")?;
19 } else if b == b'\r' {
20 write!(f, "\\r")?;
21 } else if b == b'\t' {
22 write!(f, "\\t")?;
23 } else if b == b'\\' || b == b'"' {
24 write!(f, "\\{}", b as char)?;
25 } else if b == b'\0' {
26 write!(f, "\\0")?;
27 // ASCII printable
28 } else if (0x20..0x7f).contains(&b) {
29 write!(f, "{}", b as char)?;
30 } else {
31 write!(f, "\\x{:02x}", b)?;
32 }
33 }
34 write!(f, "\"")?;
35 Ok(())
36 }
37}
38
39impl Debug for Bytes {
40 fn fmt(&self, f: &mut Formatter<'_>) -> Result {
41 Debug::fmt(&BytesRef(self.as_ref()), f)
42 }
43}
44
45impl Debug for BytesMut {
46 fn fmt(&self, f: &mut Formatter<'_>) -> Result {
47 Debug::fmt(&BytesRef(self.as_ref()), f)
48 }
49}
50