use super::utf8;
#[derive(Clone, Copy)]
pub(crate) struct Byte(pub u8);
impl core::fmt::Display for Byte {
#[inline(never)]
fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
if self.0 == b' ' {
return f.write_str(" ");
}
let mut bytes = [0u8; 10];
let mut len = 0;
for (i, mut b) in core::ascii::escape_default(self.0).enumerate() {
if i >= 2 && b'a' <= b && b <= b'f' {
b -= 32;
}
bytes[len] = b;
len += 1;
}
f.write_str(core::str::from_utf8(&bytes[..len]).unwrap())
}
}
impl core::fmt::Debug for Byte {
#[inline(never)]
fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
f.write_str("\"")?;
core::fmt::Display::fmt(self, f)?;
f.write_str("\"")?;
Ok(())
}
}
#[derive(Clone, Copy)]
pub(crate) struct Bytes<'a>(pub &'a [u8]);
impl<'a> core::fmt::Display for Bytes<'a> {
#[inline(never)]
fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
let mut bytes = self.0;
while let Some(result) = utf8::decode(bytes) {
let ch = match result {
Ok(ch) => ch,
Err(err) => {
write!(f, r"\x{:02x}", err.as_slice()[0])?;
bytes = &bytes[1..];
continue;
}
};
bytes = &bytes[ch.len_utf8()..];
match ch {
'\0' => f.write_str(r"\0")?,
'\x01'..='\x7f' => {
core::fmt::Display::fmt(&(ch as u8).escape_ascii(), f)?;
}
_ => {
core::fmt::Display::fmt(&ch.escape_debug(), f)?;
}
}
}
Ok(())
}
}
impl<'a> core::fmt::Debug for Bytes<'a> {
#[inline(never)]
fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
f.write_str("\"")?;
core::fmt::Display::fmt(self, f)?;
f.write_str("\"")?;
Ok(())
}
}
pub(crate) struct RepeatByte {
pub(crate) byte: u8,
pub(crate) count: u8,
}
impl core::fmt::Display for RepeatByte {
#[inline(never)]
fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
for _ in 0..self.count {
core::fmt::Display::fmt(&Byte(self.byte), f)?;
}
Ok(())
}
}
impl core::fmt::Debug for RepeatByte {
#[inline(never)]
fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
f.write_str("\"")?;
core::fmt::Display::fmt(self, f)?;
f.write_str("\"")?;
Ok(())
}
}