use std::any::type_name;
pub trait ByteRepr {
fn to_le_bytes(&self) -> Vec<u8>;
fn to_be_bytes(&self) -> Vec<u8>;
}
macro_rules! impl_byterep {
($t:ty) => {
impl ByteRepr for $t {
fn to_le_bytes(&self) -> Vec<u8> {
<$t>::to_le_bytes(*self).to_vec()
}
fn to_be_bytes(&self) -> Vec<u8> {
<$t>::to_be_bytes(*self).to_vec()
}
}
};
}
impl_byterep!(u8);
impl_byterep!(u16);
impl_byterep!(u32);
impl_byterep!(u64);
impl_byterep!(u128);
impl_byterep!(usize);
pub fn represent<T>(value: &T)
where
T: std::fmt::Display + std::fmt::Binary + Copy,
T: ByteRepr,
{
println!(
"\n\nHello, Representing in following formats for: {} \x1b[33m({})\x1b[0m",
value,
type_name::<T>()
);
println!(
"\x1b[31m Binary representation : {:b} \x1b[0m",
value
);
println!(
"\x1b[32m Little-endian byte array : {:?} \x1b[0m",
value.to_le_bytes()
);
println!(
"\x1b[33m Hex memory (LE) with 2-digit zero padding : {:02x?} \x1b[0m",
value.to_le_bytes()
);
println!(
"\x1b[34m Big-endian byte array : {:?} \x1b[0m",
value.to_be_bytes()
);
println!(
"\x1b[35m Hex memory (BE) with 2-digit zero padding : {:02x?} \x1b[0m",
value.to_be_bytes()
);
}
#[cfg(test)]
mod tests {
use super::*;
macro_rules! test_unsigned {
($name:ident, $ty:ty, $val:expr) => {
#[test]
fn $name() {
let val: $ty = $val;
let expected_le = val.to_le_bytes().to_vec();
let expected_be = val.to_be_bytes().to_vec();
assert_eq!(ByteRepr::to_le_bytes(&val), expected_le);
assert_eq!(ByteRepr::to_be_bytes(&val), expected_be);
}
};
}
test_unsigned!(test_u8, u8, 0x12);
test_unsigned!(test_u16, u16, 0x1234);
test_unsigned!(test_u32, u32, 0x12345678);
test_unsigned!(test_u64, u64, 0x1234567890abcdef);
test_unsigned!(test_u128, u128, 0x1234567890abcdef1122334455667788);
test_unsigned!(test_usize, usize, 0x1234);
#[test]
fn test_represent_does_not_panic() {
represent(&42u8);
represent(&42u16);
represent(&42u32);
represent(&42u64);
represent(&42u128);
represent(&42usize);
}
}