Hex wraps a value that implements fmt::LowerHex, and uses that implementation when fmt::Debug-printed ({:?}). HexSlice takes any type implementing AsRef<[u8]> and prints it as hexadecimal when printed via fmt::Debug/{:?}.
These types make it easy to quickly customize how fields are printed by wrapping them in Hex/HexSlice, which is way less work than implementing fmt::Debug by hand (and less error-prone, because #[derive(Debug)] will never forget any fields, unlike a hand-rolled impl).
The problem with them is that they conflate data with behavior by being embedded in the struct/enum definition itself instead of being part of an impl or being attributes. It takes an extra step to access a value behind them, too.
I think it would be a good idea to use custom_debug_derive instead. For that, we should add a hex and hex_slice function to utils that do what Hex and HexSlice currently do, and then use #[debug(with = "utils::hex")] on the fields that are now wrapped in Hex and #[debug(with = "utils::hex_slice")] on fields that use HexSlice.
That crate also supports specifying a format string, which is going to be quite a bit less efficient than what we have now, so it should only be used when necessary.
Hex
wraps a value that implementsfmt::LowerHex
, and uses that implementation whenfmt::Debug
-printed ({:?}
).HexSlice
takes any type implementingAsRef<[u8]>
and prints it as hexadecimal when printed viafmt::Debug
/{:?}
.These types make it easy to quickly customize how fields are printed by wrapping them in
Hex
/HexSlice
, which is way less work than implementingfmt::Debug
by hand (and less error-prone, because#[derive(Debug)]
will never forget any fields, unlike a hand-rolled impl).The problem with them is that they conflate data with behavior by being embedded in the
struct
/enum
definition itself instead of being part of an impl or being attributes. It takes an extra step to access a value behind them, too.I think it would be a good idea to use
custom_debug_derive
instead. For that, we should add ahex
andhex_slice
function toutils
that do whatHex
andHexSlice
currently do, and then use#[debug(with = "utils::hex")]
on the fields that are now wrapped inHex
and#[debug(with = "utils::hex_slice")]
on fields that useHexSlice
.That crate also supports specifying a format string, which is going to be quite a bit less efficient than what we have now, so it should only be used when necessary.