hexhex_impl/
encode.rs

1#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
2pub enum Case {
3    #[default]
4    Lower,
5    Upper,
6}
7
8/// Options for displaying bytes as hex
9#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
10pub struct DisplayOptions {
11    /// Whether '0x' (sans quotes) should be prefixed.
12    /// Note that the case option is ignored for the prefix.
13    pub with_prefix: bool,
14    /// Upper or lower case letters (A-F or a-f).
15    pub case: Case,
16}
17
18/// Wrapper struct to display bytes as hex
19#[derive(Debug, Clone, Copy)]
20pub struct Hex<T> {
21    options: DisplayOptions,
22    data: T,
23}
24
25impl<T: AsRef<[u8]>> core::fmt::Display for Hex<T> {
26    fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
27        if self.options.with_prefix {
28            write!(f, "0x")?;
29        }
30        match self.options.case {
31            Case::Lower => {
32                for byte in self.data.as_ref() {
33                    write!(f, "{byte:02x}")?;
34                }
35            }
36            Case::Upper => {
37                for byte in self.data.as_ref() {
38                    write!(f, "{byte:02X}")?;
39                }
40            }
41        }
42        Ok(())
43    }
44}
45
46impl<T: AsRef<[u8]>> Hex<T> {
47    /// Create a new wrapper struct to display the content of data as hex with default display options.
48    pub fn new(data: T) -> Self {
49        Self::new_with_options(data, DisplayOptions::default())
50    }
51
52    /// Create a new wrapper struct to display the content of data as hex with the given options.
53    pub fn new_with_options(data: T, options: DisplayOptions) -> Self {
54        Self { options, data }
55    }
56}
57
58impl<T> Hex<T> {
59    /// Use the given display options
60    pub fn with_options(mut self, options: DisplayOptions) -> Self {
61        self.options = options;
62        self
63    }
64
65    /// Display with or without prefix
66    pub fn with_prefix(mut self, with_prefix: bool) -> Self {
67        self.options.with_prefix = with_prefix;
68        self
69    }
70
71    /// Display in lower or upper case
72    pub fn with_case(mut self, case: Case) -> Self {
73        self.options.case = case;
74        self
75    }
76}
77
78/// Shorthand for [`Hex::new`]
79pub fn hex<T: AsRef<[u8]>>(data: T) -> Hex<T> {
80    Hex::new(data)
81}