jiff/shared/util/
escape.rs1use super::utf8;
8
9#[derive(Clone, Copy)]
15pub(crate) struct Byte(pub u8);
16
17impl core::fmt::Display for Byte {
18 fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
19 if self.0 == b' ' {
20 return write!(f, " ");
21 }
22 let mut bytes = [0u8; 10];
24 let mut len = 0;
25 for (i, mut b) in core::ascii::escape_default(self.0).enumerate() {
26 if i >= 2 && b'a' <= b && b <= b'f' {
28 b -= 32;
29 }
30 bytes[len] = b;
31 len += 1;
32 }
33 write!(f, "{}", core::str::from_utf8(&bytes[..len]).unwrap())
34 }
35}
36
37impl core::fmt::Debug for Byte {
38 fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
39 write!(f, "\"")?;
40 core::fmt::Display::fmt(self, f)?;
41 write!(f, "\"")?;
42 Ok(())
43 }
44}
45
46#[derive(Clone, Copy)]
52pub(crate) struct Bytes<'a>(pub &'a [u8]);
53
54impl<'a> core::fmt::Display for Bytes<'a> {
55 fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
56 let mut bytes = self.0;
58 while let Some(result) = utf8::decode(bytes) {
59 let ch = match result {
60 Ok(ch) => ch,
61 Err(byte) => {
62 write!(f, r"\x{:02x}", byte)?;
63 bytes = &bytes[1..];
64 continue;
65 }
66 };
67 bytes = &bytes[ch.len_utf8()..];
68 match ch {
69 '\0' => write!(f, "\\0")?,
70 '\x01'..='\x7f' => {
71 write!(f, "{}", (ch as u8).escape_ascii())?;
72 }
73 _ => write!(f, "{}", ch.escape_debug())?,
74 }
75 }
76 Ok(())
77 }
78}
79
80impl<'a> core::fmt::Debug for Bytes<'a> {
81 fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
82 write!(f, "\"")?;
83 core::fmt::Display::fmt(self, f)?;
84 write!(f, "\"")?;
85 Ok(())
86 }
87}