133d722a9Sopenharmony_ciuse core::char;
233d722a9Sopenharmony_ciuse core::fmt::{self, Write as _};
333d722a9Sopenharmony_ciuse core::str;
433d722a9Sopenharmony_ci
533d722a9Sopenharmony_cipub fn display(mut bytes: &[u8], f: &mut fmt::Formatter) -> fmt::Result {
633d722a9Sopenharmony_ci    loop {
733d722a9Sopenharmony_ci        match str::from_utf8(bytes) {
833d722a9Sopenharmony_ci            Ok(valid) => return f.write_str(valid),
933d722a9Sopenharmony_ci            Err(utf8_error) => {
1033d722a9Sopenharmony_ci                let valid_up_to = utf8_error.valid_up_to();
1133d722a9Sopenharmony_ci                let valid = unsafe { str::from_utf8_unchecked(&bytes[..valid_up_to]) };
1233d722a9Sopenharmony_ci                f.write_str(valid)?;
1333d722a9Sopenharmony_ci                f.write_char(char::REPLACEMENT_CHARACTER)?;
1433d722a9Sopenharmony_ci                if let Some(error_len) = utf8_error.error_len() {
1533d722a9Sopenharmony_ci                    bytes = &bytes[valid_up_to + error_len..];
1633d722a9Sopenharmony_ci                } else {
1733d722a9Sopenharmony_ci                    return Ok(());
1833d722a9Sopenharmony_ci                }
1933d722a9Sopenharmony_ci            }
2033d722a9Sopenharmony_ci        }
2133d722a9Sopenharmony_ci    }
2233d722a9Sopenharmony_ci}
2333d722a9Sopenharmony_ci
2433d722a9Sopenharmony_cipub fn debug(mut bytes: &[u8], f: &mut fmt::Formatter) -> fmt::Result {
2533d722a9Sopenharmony_ci    f.write_char('"')?;
2633d722a9Sopenharmony_ci
2733d722a9Sopenharmony_ci    while !bytes.is_empty() {
2833d722a9Sopenharmony_ci        let from_utf8_result = str::from_utf8(bytes);
2933d722a9Sopenharmony_ci        let valid = match from_utf8_result {
3033d722a9Sopenharmony_ci            Ok(valid) => valid,
3133d722a9Sopenharmony_ci            Err(utf8_error) => {
3233d722a9Sopenharmony_ci                let valid_up_to = utf8_error.valid_up_to();
3333d722a9Sopenharmony_ci                unsafe { str::from_utf8_unchecked(&bytes[..valid_up_to]) }
3433d722a9Sopenharmony_ci            }
3533d722a9Sopenharmony_ci        };
3633d722a9Sopenharmony_ci
3733d722a9Sopenharmony_ci        let mut written = 0;
3833d722a9Sopenharmony_ci        for (i, ch) in valid.char_indices() {
3933d722a9Sopenharmony_ci            let esc = ch.escape_debug();
4033d722a9Sopenharmony_ci            if esc.len() != 1 && ch != '\'' {
4133d722a9Sopenharmony_ci                f.write_str(&valid[written..i])?;
4233d722a9Sopenharmony_ci                for ch in esc {
4333d722a9Sopenharmony_ci                    f.write_char(ch)?;
4433d722a9Sopenharmony_ci                }
4533d722a9Sopenharmony_ci                written = i + ch.len_utf8();
4633d722a9Sopenharmony_ci            }
4733d722a9Sopenharmony_ci        }
4833d722a9Sopenharmony_ci        f.write_str(&valid[written..])?;
4933d722a9Sopenharmony_ci
5033d722a9Sopenharmony_ci        match from_utf8_result {
5133d722a9Sopenharmony_ci            Ok(_valid) => break,
5233d722a9Sopenharmony_ci            Err(utf8_error) => {
5333d722a9Sopenharmony_ci                let end_of_broken = if let Some(error_len) = utf8_error.error_len() {
5433d722a9Sopenharmony_ci                    valid.len() + error_len
5533d722a9Sopenharmony_ci                } else {
5633d722a9Sopenharmony_ci                    bytes.len()
5733d722a9Sopenharmony_ci                };
5833d722a9Sopenharmony_ci                for b in &bytes[valid.len()..end_of_broken] {
5933d722a9Sopenharmony_ci                    write!(f, "\\x{:02x}", b)?;
6033d722a9Sopenharmony_ci                }
6133d722a9Sopenharmony_ci                bytes = &bytes[end_of_broken..];
6233d722a9Sopenharmony_ci            }
6333d722a9Sopenharmony_ci        }
6433d722a9Sopenharmony_ci    }
6533d722a9Sopenharmony_ci
6633d722a9Sopenharmony_ci    f.write_char('"')
6733d722a9Sopenharmony_ci}
68