#[cfg(not(feature = "std"))]
extern crate alloc;
#[cfg(not(feature = "std"))]
use alloc::vec::Vec;
pub fn hex(d: &[u8]) -> HexDisplay {
HexDisplay(d)
}
#[derive(Eq, PartialEq)]
pub struct HexDisplay<'a>(&'a [u8]);
impl<'a> HexDisplay<'a> {
pub fn from<R: AsBytesRef>(d: &'a R) -> Self {
HexDisplay(d.as_bytes_ref())
}
}
impl<'a> core::fmt::Display for HexDisplay<'a> {
fn fmt(&self, f: &mut core::fmt::Formatter) -> Result<(), core::fmt::Error> {
if self.0.len() < 1027 {
for byte in self.0 {
f.write_fmt(format_args!("{:02x}", byte))?;
}
} else {
for byte in &self.0[0..512] {
f.write_fmt(format_args!("{:02x}", byte))?;
}
f.write_str("...")?;
for byte in &self.0[self.0.len() - 512..] {
f.write_fmt(format_args!("{:02x}", byte))?;
}
}
Ok(())
}
}
impl<'a> core::fmt::Debug for HexDisplay<'a> {
fn fmt(&self, f: &mut core::fmt::Formatter) -> Result<(), core::fmt::Error> {
if self.0.iter().all(|b| b.is_ascii_graphic() || b.is_ascii_whitespace()) {
let s = core::str::from_utf8(self.0).map_err(|_| core::fmt::Error)?;
return core::fmt::Debug::fmt(&s, f);
}
for byte in self.0 {
f.write_fmt(format_args!("{:02x}", byte))?;
}
Ok(())
}
}
pub trait AsBytesRef {
fn as_bytes_ref(&self) -> &[u8];
}
impl AsBytesRef for &[u8] {
fn as_bytes_ref(&self) -> &[u8] {
self
}
}
impl AsBytesRef for [u8] {
fn as_bytes_ref(&self) -> &[u8] {
self
}
}
impl AsBytesRef for Vec<u8> {
fn as_bytes_ref(&self) -> &[u8] {
self
}
}
macro_rules! impl_array {
( $( $t:ty ),* ) => { $(
impl AsBytesRef for $t {
fn as_bytes_ref(&self) -> &[u8] { &self[..] }
}
)* }
}
impl_array!([u8; 32]);