pub fn is_set(field: bool) -> char {
match field {
true => '+',
false => '-',
}
}
pub fn format_bytes(size: u64) -> String {
let mut s = size;
let mut divs: u8 = 0;
while s / 1024 >= 1 {
s /= 1024;
divs += 1;
}
format!(
"{}{}",
s.to_string(),
match divs {
0 => "B",
1 => "K",
2 => "M",
3 => "G",
4 => "T",
_ => return size.to_string(),
}
)
}
const SLICE_SIZE: usize = 16;
pub struct Hexdumper<'a> {
pub bytes: &'a [u8],
pub show_header: bool,
pub show_ascii: bool,
pub offset: Option<u64>,
}
impl std::fmt::Display for Hexdumper<'_> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let size = std::cmp::min(self.bytes.len(), SLICE_SIZE);
if self.show_header {
write!(f, " ")?;
for col in 0..size {
write!(f, " {:1x} ", col)?;
if col == 7 {
write!(f, " ")?;
}
}
writeln!(f)?;
}
let start_addr = self.offset.unwrap_or(0) as usize;
for (addr, slice) in self.bytes.chunks(SLICE_SIZE).enumerate() {
write!(f, " {:04x}: ", start_addr + (addr * SLICE_SIZE))?;
for (i, byte) in slice.iter().enumerate() {
write!(f, "{:02x} ", byte)?;
if i == 7 {
write!(f, " ")?;
}
}
if self.show_ascii {
write!(f, " ")?;
for byte in slice {
if byte.is_ascii_graphic() {
write!(f, "{}", *byte as char)?;
} else {
write!(f, ".")?;
}
}
}
writeln!(f)?;
}
Ok(())
}
}