byte_repr/lib.rs
1use std::any::type_name;
2
3/// A trait to extract little-endian and big-endian byte representations
4/// for any type that supports `to_le_bytes()` and `to_be_bytes()`.
5///
6/// # Examples
7///
8/// ```rust
9/// use byte_repr::ByteRepr;
10///
11/// let num: u32 = 0x01020304;
12/// assert_eq!(num.to_le_bytes().to_vec(), vec![0x04, 0x03, 0x02, 0x01]);
13/// assert_eq!(num.to_be_bytes().to_vec(), vec![0x01, 0x02, 0x03, 0x04]);
14/// ```
15pub trait ByteRepr {
16 /// Returns the little-endian byte representation of the value as a `Vec<u8>`.
17 fn to_le_bytes(&self) -> Vec<u8>;
18
19 /// Returns the big-endian byte representation of the value as a `Vec<u8>`.
20 fn to_be_bytes(&self) -> Vec<u8>;
21}
22
23/// A macro to implement the `ByteRepr` trait for primitive numeric types
24/// (e.g., `u8`, `u16`, `u32`, `f64`, etc.).
25///
26/// It uses the type's built-in methods `to_le_bytes()` and `to_be_bytes()`
27/// and converts the resulting fixed-size byte arrays into dynamic vectors.
28macro_rules! impl_byterep {
29 ($t:ty) => {
30 impl ByteRepr for $t {
31 fn to_le_bytes(&self) -> Vec<u8> {
32 <$t>::to_le_bytes(*self).to_vec()
33 }
34 fn to_be_bytes(&self) -> Vec<u8> {
35 <$t>::to_be_bytes(*self).to_vec()
36 }
37 }
38 };
39}
40
41// Implement ByteRepr for all unsigned integer types
42impl_byterep!(u8);
43impl_byterep!(u16);
44impl_byterep!(u32);
45impl_byterep!(u64);
46impl_byterep!(u128);
47impl_byterep!(usize);
48
49/// A generic function that prints multiple memory-level representations
50/// of a numeric value, including binary, little-endian, and big-endian formats.
51///
52/// It supports:
53/// - Binary view
54/// - Little-endian byte array and hex
55/// - Big-endian byte array and hex
56///
57/// # Requirements:
58/// - The type must implement `Display`, `Binary`, `Copy`, and `ByteRepr`.
59///
60/// # Color Codes (Terminal):
61/// - Binary: Red
62/// - LE Bytes: Green
63/// - LE Hex: Yellow
64/// - BE Bytes: Blue
65/// - BE Hex: Magenta
66///
67/// # Examples
68///
69/// ```rust
70/// use byte_repr::represent;
71/// let x = 255u8;
72/// represent(&x);
73///
74/// let x = 65535u16;
75/// represent(&x);
76///
77/// let x = 4294967295u32;
78/// represent(&x);
79///
80/// let x = 18446744073709551615u64;
81/// represent(&x);
82///
83/// let x = 340282366920938463463374607431768211455u128;
84/// represent(&x);
85///
86/// let x = 18446744073709551615usize;
87/// represent(&x);
88/// ```
89pub fn represent<T>(value: &T)
90where
91 T: std::fmt::Display + std::fmt::Binary + Copy,
92 T: ByteRepr,
93{
94 println!(
95 "\n\nHello, Representing in following formats for: {} \x1b[33m({})\x1b[0m",
96 value,
97 type_name::<T>()
98 );
99
100 // Binary
101 println!(
102 "\x1b[31m Binary representation : {:b} \x1b[0m",
103 value
104 );
105
106 // Little-endian bytes
107 println!(
108 "\x1b[32m Little-endian byte array : {:?} \x1b[0m",
109 value.to_le_bytes()
110 );
111 println!(
112 "\x1b[33m Hex memory (LE) with 2-digit zero padding : {:02x?} \x1b[0m",
113 value.to_le_bytes()
114 );
115
116 // Big-endian bytes
117 println!(
118 "\x1b[34m Big-endian byte array : {:?} \x1b[0m",
119 value.to_be_bytes()
120 );
121 println!(
122 "\x1b[35m Hex memory (BE) with 2-digit zero padding : {:02x?} \x1b[0m",
123 value.to_be_bytes()
124 );
125}
126
127#[cfg(test)]
128mod tests {
129 use super::*;
130
131 macro_rules! test_unsigned {
132 ($name:ident, $ty:ty, $val:expr) => {
133 #[test]
134 fn $name() {
135 let val: $ty = $val;
136 let expected_le = val.to_le_bytes().to_vec();
137 let expected_be = val.to_be_bytes().to_vec();
138 assert_eq!(ByteRepr::to_le_bytes(&val), expected_le);
139 assert_eq!(ByteRepr::to_be_bytes(&val), expected_be);
140 }
141 };
142 }
143
144 test_unsigned!(test_u8, u8, 0x12);
145 test_unsigned!(test_u16, u16, 0x1234);
146 test_unsigned!(test_u32, u32, 0x12345678);
147 test_unsigned!(test_u64, u64, 0x1234567890abcdef);
148 test_unsigned!(test_u128, u128, 0x1234567890abcdef1122334455667788);
149 test_unsigned!(test_usize, usize, 0x1234);
150
151 #[test]
152 fn test_represent_does_not_panic() {
153 represent(&42u8);
154 represent(&42u16);
155 represent(&42u32);
156 represent(&42u64);
157 represent(&42u128);
158 represent(&42usize);
159 }
160}