I have multiple structs where I want to format elements containing byte containers to hexadecimals strings. At the moment I have this implemented by overriding their fmt::Display in the following way:
use std::fmt;
#[derive(Debug)]
struct Foo {
bar: Vec<u8>,
baz: [u8; 2],
}
impl fmt::Display for Foo {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let bar = self.bar.iter().map(|b| format!("{:02X}", b)).collect::<String>();
let baz = self.baz.iter().map(|b| format!("{:02X}", b)).collect::<String>();
write!(f, "Foo {{ bar: 0x{}, baz: 0x{} }}", bar, baz)
}
}
fn main() {
let foo = Foo {bar: vec![0x1, 0x2, 0x3], baz: [0x4, 0x5]};
println!("Debug output: {:?}", foo);
println!("Desired output: {}", foo);
}
Output:
Debug output: Foo { bar: [1, 2, 3], baz: [4, 5] }
Desired output: Foo { bar: 0x010203, baz: 0x0405 }
With multiple structs, this leads to a bit of duplicate code.
Is there a more convenient way to implement this? For instance a macro similar to Debug that handles Vec<u8> and [u8] as hex strings?