1#![no_std]
2#![doc = include_str!("../README.md")]
3
4use core::fmt::{Debug, Display, LowerHex, UpperHex};
5
6#[cfg(any(feature = "std", test))]
7extern crate std;
8
9#[cfg(feature = "alloc")]
10extern crate alloc;
11
12pub trait HexDisplayExt {
26 fn hex(&self) -> Hex<'_>;
28
29 #[cfg(feature = "alloc")]
33 fn upper_hex_string(&self) -> alloc::string::String {
34 alloc::format!("{:X}", self.hex())
35 }
36
37 #[cfg(feature = "alloc")]
41 fn hex_string(&self) -> alloc::string::String {
42 use alloc::string::ToString;
43 self.hex().to_string()
44 }
45}
46
47impl HexDisplayExt for [u8] {
48 fn hex(&self) -> Hex<'_> {
49 Hex(self)
50 }
51}
52
53impl<const N: usize> HexDisplayExt for [u8; N] {
54 fn hex(&self) -> Hex<'_> {
55 Hex(self)
56 }
57}
58
59pub struct Hex<'a>(
83 pub &'a [u8],
85);
86
87impl UpperHex for Hex<'_> {
88 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
89 for byte in self.0 {
90 f.write_fmt(format_args!("{:02X}", byte))?;
91 }
92 Ok(())
93 }
94}
95impl LowerHex for Hex<'_> {
96 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
97 for byte in self.0 {
98 f.write_fmt(format_args!("{:02x}", byte))?;
99 }
100 Ok(())
101 }
102}
103impl Debug for Hex<'_> {
104 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
105 for byte in self.0 {
106 f.write_fmt(format_args!("{:02x}", byte))?;
107 }
108 Ok(())
109 }
110}
111impl Display for Hex<'_> {
112 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
113 for byte in self.0 {
114 f.write_fmt(format_args!("{:02x}", byte))?;
115 }
116 Ok(())
117 }
118}
119
120#[cfg(test)]
121mod tests {
122 use std::format;
123
124 use super::*;
125
126 #[test]
127 fn test_all_bytes() {
128 for byte in 0..=0xff {
129 assert_eq!(format!("{:02x}", byte), format!("{}", Hex(&[byte])));
130 assert_eq!(format!("{:02X}", byte), format!("{:X}", Hex(&[byte])));
131 }
132 }
133
134 #[test]
135 fn test_all_byte_pairs() {
136 for (a, b) in (0..=0xff).zip(0..=0xff) {
137 assert_eq!(format!("{:02x}{:02x}", a, b), format!("{}", Hex(&[a, b])));
138 assert_eq!(format!("{:02X}{:02X}", a, b), format!("{:X}", Hex(&[a, b])));
139 }
140 }
141}