Skip to main content

fashex/
display.rs

1use alloc::vec::Vec;
2use core::fmt;
3
4use crate::encode;
5
6wrapper_lite::wrapper!(
7    #[wrapper(Debug)]
8    #[wrapper(AsRef)]
9    #[wrapper([const] AsMut)]
10    #[wrapper(BorrowMut)]
11    #[wrapper(DerefMut)]
12    #[wrapper(From)]
13    #[bound(T: AsRef<[u8]>)]
14    #[cfg_attr(docsrs, doc(cfg(feature = "alloc")))]
15    #[derive(Clone, Copy, PartialEq, Eq)]
16    /// A wrapper for displaying a byte slice as a hexadecimal string.
17    ///
18    /// ```rust
19    /// let bytes = &[0xde, 0xad, 0xbe, 0xef];
20    ///
21    /// let displayed = fashex::Display::from(bytes);
22    ///
23    /// assert_eq!(format!("{}", &displayed), "deadbeef");
24    /// assert_eq!(format!("{:X}", &displayed), "DEADBEEF");
25    /// assert_eq!(format!("{:#x}", &displayed), "0xdeadbeef");
26    /// assert_eq!(format!("{:#X}", &displayed), "0xDEADBEEF");
27    /// ```
28    pub struct Display<T> {
29        value: T,
30    }
31);
32
33impl<T: AsRef<[u8]>> fmt::Display for Display<T> {
34    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
35        fmt::LowerHex::fmt(self, f)
36    }
37}
38
39impl<T: AsRef<[u8]>> fmt::LowerHex for Display<T> {
40    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
41        self.write::<false>(f)
42    }
43}
44
45impl<T: AsRef<[u8]>> fmt::UpperHex for Display<T> {
46    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
47        self.write::<true>(f)
48    }
49}
50
51impl<T> Display<T>
52where
53    T: AsRef<[u8]>,
54{
55    fn write<const UPPER: bool>(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
56        let src = self.as_inner().as_ref();
57
58        let mut buf = Vec::with_capacity(src.len() * 2 + 2);
59
60        if f.alternate() {
61            buf.extend(b"0x");
62        }
63
64        encode::<UPPER>(src, &mut buf).map_err(|_| fmt::Error)?;
65
66        #[allow(unsafe_code, reason = "XXX")]
67        let buf = unsafe { str::from_utf8_unchecked(&buf) };
68
69        f.write_str(buf)
70    }
71}