• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 use core::char;
2 use core::fmt::{self, Write as _};
3 use core::str;
4 
display(mut bytes: &[u8], f: &mut fmt::Formatter) -> fmt::Result5 pub fn display(mut bytes: &[u8], f: &mut fmt::Formatter) -> fmt::Result {
6     loop {
7         match str::from_utf8(bytes) {
8             Ok(valid) => return f.write_str(valid),
9             Err(utf8_error) => {
10                 let valid_up_to = utf8_error.valid_up_to();
11                 let valid = unsafe { str::from_utf8_unchecked(&bytes[..valid_up_to]) };
12                 f.write_str(valid)?;
13                 f.write_char(char::REPLACEMENT_CHARACTER)?;
14                 if let Some(error_len) = utf8_error.error_len() {
15                     bytes = &bytes[valid_up_to + error_len..];
16                 } else {
17                     return Ok(());
18                 }
19             }
20         }
21     }
22 }
23 
debug(mut bytes: &[u8], f: &mut fmt::Formatter) -> fmt::Result24 pub fn debug(mut bytes: &[u8], f: &mut fmt::Formatter) -> fmt::Result {
25     f.write_char('"')?;
26 
27     while !bytes.is_empty() {
28         let from_utf8_result = str::from_utf8(bytes);
29         let valid = match from_utf8_result {
30             Ok(valid) => valid,
31             Err(utf8_error) => {
32                 let valid_up_to = utf8_error.valid_up_to();
33                 unsafe { str::from_utf8_unchecked(&bytes[..valid_up_to]) }
34             }
35         };
36 
37         let mut written = 0;
38         for (i, ch) in valid.char_indices() {
39             let esc = ch.escape_debug();
40             if esc.len() != 1 {
41                 f.write_str(&valid[written..i])?;
42                 for ch in esc {
43                     f.write_char(ch)?;
44                 }
45                 written = i + ch.len_utf8();
46             }
47         }
48         f.write_str(&valid[written..])?;
49 
50         match from_utf8_result {
51             Ok(_valid) => break,
52             Err(utf8_error) => {
53                 let end_of_broken = if let Some(error_len) = utf8_error.error_len() {
54                     valid.len() + error_len
55                 } else {
56                     bytes.len()
57                 };
58                 for b in &bytes[valid.len()..end_of_broken] {
59                     write!(f, "\\x{:02x}", b)?;
60                 }
61                 bytes = &bytes[end_of_broken..];
62             }
63         }
64     }
65 
66     f.write_char('"')
67 }
68