1 use core::char; 2 use core::fmt::{self, Write as _}; 3 use core::str; 4 displaynull5pub 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 debugnull24pub 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 && ch != '\'' { 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