tesap_std/
bytes.rs

1use crate::vector as my;
2use crate::chunks::Chunks;
3use std::fmt;
4use std::mem;
5
6// === Formats ===
7// bytes: (&[u8]) [x01, xf3, x7d, x19]
8//   This serve as a common ground for all conversions
9// int: (i64) 3485392
10// bin: (str) "01010101010100110"
11// hex: (str) "3bed02d1d149e5336349707ce47d6c90"
12
13
14fn u8_to_bin(n: &u8) -> Bin {
15    format!("{:08b}", n)
16}
17
18fn bin_to_u8(b: &Bin) -> u8 {
19    u8::from_str_radix(b, 2).expect("Invalid binary string")
20}
21
22fn u8_to_hex(n: &u8) -> String {
23    format!("{:02x}", n)
24}
25
26fn hex_to_u8(h: &str) -> u8 {
27    u8::from_str_radix(h, 16).expect("Invalid hex string")
28}
29
30type Byte = u8;
31
32#[derive(Debug)]
33pub struct Bytes<const BIG_ENDIAN: bool = true>{
34    pub vec: my::Vector<Byte>
35}
36
37#[derive(Clone, Debug)]
38pub struct Hex(pub String);
39
40pub type Bin = String;
41
42#[derive(Debug)]
43pub struct Bins(pub my::Vector<Bin>);
44
45impl Into<String> for &Bins {
46    fn into(self) -> String {
47        self.0.join(" ")
48    }
49}
50
51pub trait DebugBytes {
52    fn print(&self);
53}
54
55impl fmt::Display for Hex {
56    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
57        write!(f, "{:}", self.0)
58    }
59}
60
61impl DebugBytes for Bytes<true> {
62    fn print(&self) {
63        println!("\n----> Bytes: {:?}", self);
64        self.as_slice().print();
65        self.to_int128().unwrap().print();
66        self.to_bin().print();
67        self.to_hex().print();
68        println!();
69    }
70}
71
72impl DebugBytes for i128 {
73    fn print(&self) {
74        let p: *const i128 = &*self;
75
76        let view: Chunks<Byte> = Chunks {
77            ptr: p as *mut Byte,
78            count: 16
79        };
80        println!("-> i128: {:?}; {:?}", self, view);
81        std::mem::forget(view);
82    }
83}
84
85impl DebugBytes for &[Byte] {
86    fn print(&self) {
87        println!("-> &[u8]: {:?}", self);
88    }
89}
90
91impl DebugBytes for Hex {
92    fn print(&self) {
93        println!("-> Hex: {:?}", self.0);
94    }
95}
96
97impl DebugBytes for Bins {
98    fn print(&self) {
99        let s: String = self.into();
100        println!("-> Bins: [{:}]", s);
101    }
102}
103
104impl<const BE: bool> Bytes<BE> {
105    pub fn as_slice(&self) -> &[Byte] {
106        self.vec.as_slice()
107    }
108
109    pub fn to_int128(&self) -> Result<i128, String> {
110        let s1 = size_of::<i128>();
111        let s2 = self.vec.len_bytes();
112
113        if s2 > s1 {
114            return Err("Bytes length is too big".to_string());
115        }
116
117        let ptr: *const i128 = self.vec.as_ptr() as *const i128;
118        unsafe {
119            Ok(*ptr)
120        }
121    }
122
123    pub fn to_bin(&self) -> Bins {
124        let v: my::Vector<Bin> = self.vec.iter().map(u8_to_bin).collect();
125        let a = Bins(v);
126        a
127    }
128
129    pub fn to_hex(&self) -> Hex {
130        let hex_string = self.vec.iter()
131            .map(u8_to_hex)
132            .collect::<String>();
133        Hex(hex_string)
134    }
135
136    pub fn from_bytes(from: &[Byte]) -> Self {
137        Self {
138            vec: my::Vector::from_slice_copy(from)
139        }
140    }
141
142    // WHAT? If we pass 'from' by value, further from_slice fails with error referencing
143    // i.e. value is dropped (right?)
144    pub fn from_int(from: &i128) -> Self {
145        // Direct cast doesn't work, but intermediate does
146        let ptr: *const i128 = from;
147        // Casting from const to mut is legal
148        let ptr_u8: *mut u8 = ptr as *mut u8;
149
150        // Why *mut type is needed?
151        let size: usize = mem::size_of::<i128>() / mem::size_of::<Byte>();
152
153        // --> Doesnt work
154        // let slice: *const [Byte] = ptr as *const [Byte];
155
156        // --> Is it prefferred option over direct slice constructor?
157        // Constructing wide pointer
158        // let nn_ptr = ptr::NonNull::new(ptr_u8).unwrap();
159        //let slice = unsafe {
160        //    ptr::NonNull::slice_from_raw_parts(nn_ptr, size).as_mut()
161        //};
162
163        // TODO Chunks
164        // --> Manually create slice
165        let slice = unsafe {
166            std::slice::from_raw_parts(ptr_u8, size)
167        };
168
169        Self {
170            vec: my::Vector::from_slice_copy(slice)
171        }
172    }
173
174    pub fn from_bins(from: &Bins) -> Self {
175        let bytes: my::Vector<Byte> = from.0.iter().map(bin_to_u8).collect();
176        Self {
177            vec: bytes
178        }
179    }
180
181    pub fn from_hex(from: &Hex) -> Self {
182        let mut v: my::Vector<Byte> = my::Vector::new();
183        for i in (0..from.0.len()).step_by(2) {
184            // What is &x[..] expression?
185            let b: u8 = hex_to_u8(&from.0[i..i+2]);
186            v.push(b);
187        }
188
189        Self {
190            vec: v
191        }
192    }
193}