use std::borrow::Cow;
use pretty_hex::PrettyHex;
pub struct LimitedHex<'a> {
first: &'a [u8],
second: &'a [u8],
full_len: usize,
}
impl<'a> LimitedHex<'a> {
pub fn new(inner: &'a [u8], max_bytes: usize) -> Self {
let truncated_len = inner.len().min(max_bytes);
Self {
first: &inner[..truncated_len],
second: &[],
full_len: inner.len(),
}
}
pub fn from_split(split: crate::inputs::Split<'a>, max_bytes: usize) -> Self {
use crate::inputs::Input as _;
let full_len = split.len();
let len = full_len.min(max_bytes);
let mut truncated = split;
let truncated = truncated.next_slice(len);
let (first, second) = truncated.slices();
Self {
first,
second,
full_len,
}
}
fn to_cow(&self) -> Cow<'a, [u8]> {
if self.second.is_empty() {
Cow::Borrowed(self.first)
} else {
let mut v = Vec::with_capacity(self.first.len() + self.second.len());
v.extend_from_slice(self.first);
v.extend_from_slice(self.second);
Cow::Owned(v)
}
}
fn omitted(&self) -> usize {
self.full_len - self.first.len() - self.second.len()
}
}
impl std::fmt::Display for LimitedHex<'_> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let data = self.to_cow();
let hex = data.hex_conf(pretty_hex::HexConfig {
title: false,
width: 0,
group: 0,
chunk: 0,
..Default::default()
});
write!(f, "Length: {0} (0x{0:x}) bytes\n{hex:#}", self.full_len)?;
let omitted = self.omitted();
if omitted > 0 {
write!(f, "\n...{0} (0x{0:x}) bytes not shown...", omitted)?;
}
Ok(())
}
}
impl std::fmt::Debug for LimitedHex<'_> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let data = self.to_cow();
let hex = data.hex_conf(pretty_hex::HexConfig {
title: false,
..Default::default()
});
write!(f, "Length: {0} (0x{0:x}) bytes\n{hex:#?}", self.full_len)?;
let omitted = self.omitted();
if omitted > 0 {
write!(f, "\n...{0} (0x{0:x}) bytes not shown...", omitted)?;
}
Ok(())
}
}