1macro_rules! impl_base {
2 ($name:ident, $type:ty) => {
3 impl ::std::fmt::Debug for Hex<$type> {
4 fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
5 impl_base_fmt(f, self.0)
6 }
7 }
8
9 impl ::std::fmt::Display for Hex<$type> {
10 fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
11 impl_base_fmt(f, self.0)
12 }
13 }
14 };
15}
16
17fn impl_base_fmt<T>(f: &mut ::std::fmt::Formatter, data: T) -> ::std::fmt::Result
18where
19 T: Copy + ::std::fmt::LowerHex,
20{
21 match size_of::<T>() {
22 1 => write!(f, "0x{:02x}", data),
23 2 => write!(f, "0x{:04x}", data),
24 4 => write!(f, "0x{:08x}", data),
25 8 => write!(f, "0x{:016x}", data),
26 _ => write!(f, "0x{:x}", data),
27 }
28}
29
30macro_rules! impl_sequence {
31 ($name:ident, $type:ty) => {
32 impl ::std::fmt::Debug for Hex<$type> {
33 fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
34 impl_base_sequence(f, &self.0)
35 }
36 }
37
38 impl ::std::fmt::Display for Hex<$type> {
39 fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
40 impl_base_sequence(f, &self.0)
41 }
42 }
43 };
44}
45
46fn impl_base_sequence<T>(f: &mut ::std::fmt::Formatter, data: impl AsRef<[T]>) -> ::std::fmt::Result
47where
48 T: Copy + ::std::fmt::LowerHex,
49{
50 let data = data.as_ref();
51
52 if data.is_empty() {
53 return write!(f, "[]");
54 }
55
56 write!(f, "[")?;
57
58 for (index, item) in data.iter().enumerate() {
59 impl_base_fmt(f, *item)?;
60
61 if index < data.len() - 1 {
62 write!(f, ", ")?;
63 }
64 }
65
66 write!(f, "]")
67}
68
69macro_rules! impl_ops {
70 ($name:ident, $type:ty) => {
71 impl_base!($name, $type);
72 impl_sequence!($name, &Vec<$type>);
73 impl_sequence!($name, &[$type]);
74 };
75}
76
77pub struct Hex<T>(pub T);
88
89impl_ops!(Hex, i8);
90impl_ops!(Hex, i16);
91impl_ops!(Hex, i32);
92impl_ops!(Hex, i64);
93
94impl_ops!(Hex, u8);
95impl_ops!(Hex, u16);
96impl_ops!(Hex, u32);
97impl_ops!(Hex, u64);
98
99impl_ops!(Hex, isize);
100impl_ops!(Hex, usize);