#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
pub enum Case {
#[default]
Lower,
Upper,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
pub struct DisplayOptions {
pub with_prefix: bool,
pub case: Case,
}
#[derive(Debug, Clone, Copy)]
pub struct Hex<T> {
options: DisplayOptions,
data: T,
}
impl<T: AsRef<[u8]>> core::fmt::Display for Hex<T> {
fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
if self.options.with_prefix {
write!(f, "0x")?;
}
match self.options.case {
Case::Lower => {
for byte in self.data.as_ref() {
write!(f, "{byte:02x}")?;
}
}
Case::Upper => {
for byte in self.data.as_ref() {
write!(f, "{byte:02X}")?;
}
}
}
Ok(())
}
}
impl<T: AsRef<[u8]>> Hex<T> {
pub fn new(data: T) -> Self {
Self::new_with_options(data, DisplayOptions::default())
}
pub fn new_with_options(data: T, options: DisplayOptions) -> Self {
Self { options, data }
}
}
impl<T> Hex<T> {
pub fn with_options(mut self, options: DisplayOptions) -> Self {
self.options = options;
self
}
pub fn with_prefix(mut self, with_prefix: bool) -> Self {
self.options.with_prefix = with_prefix;
self
}
pub fn with_case(mut self, case: Case) -> Self {
self.options.case = case;
self
}
}
pub fn hex<T: AsRef<[u8]>>(data: T) -> Hex<T> {
Hex::new(data)
}