1
2use std::error::Error;
3
4pub fn encode<T, I>(iterable: I) -> Result<Vec<u8>, Box<dyn Error>>
5where
6 T: IntoBytes,
7 I: IntoIterator<Item = T>,
8{
9
10 let mut result: Vec<u8> = Vec::new();
11
12 for item in iterable {
13
14 let item_buffer = item.into_bytes();
15
16 if item_buffer.len() > 4294967295 {
17
18 result.push(8);
19
20 result.extend((item_buffer.len() as u64).to_le_bytes());
21
22 } else if item_buffer.len() > 65535 {
23
24 result.push(4);
25
26 result.extend((item_buffer.len() as u32).to_le_bytes());
27
28 } else if item_buffer.len() > 255 {
29
30 result.push(2);
31
32 result.extend((item_buffer.len() as u16).to_le_bytes());
33
34 } else if item_buffer.len() > 0 {
35
36 result.push(1);
37
38 result.extend((item_buffer.len() as u8).to_le_bytes());
39
40 } else {
41
42 result.push(0);
43
44 };
45
46 result.extend(item_buffer)
47
48 }
49
50 Ok(result)
51
52}
53
54
55pub fn decode<'a, T>(buffer: &'a [u8]) -> Result<Vec<T>, Box<dyn Error>>
56where
57 T: TryFromBytes<'a>,
58{
59
60 let mut decoded_data = Vec::new();
61 let mut offset = 0;
62
63 while offset < buffer.len() {
64
65 let length_type = buffer[offset];
66
67 offset += 1;
68
69 let item_len: usize = match length_type {
70 0 => 0,
71 1 => buffer[offset] as usize,
72 2 => u16::from_le_bytes([
73 buffer[offset],
74 buffer[offset + 1],
75 ]) as usize,
76 4 => u32::from_le_bytes([
77 buffer[offset],
78 buffer[offset + 1],
79 buffer[offset + 2],
80 buffer[offset + 3],
81 ]) as usize,
82 8 => u64::from_le_bytes([
83 buffer[offset],
84 buffer[offset + 1],
85 buffer[offset + 2],
86 buffer[offset + 3],
87 buffer[offset + 4],
88 buffer[offset + 5],
89 buffer[offset + 6],
90 buffer[offset + 7],
91 ]) as usize,
92 _ => return Err("Invalid length type".into()),
93 };
94
95 offset += length_type as usize;
96
97 if offset + item_len <= buffer.len() {
98 let item_data = &buffer[offset..offset + item_len];
99 offset += item_len;
100 let item = T::try_from_bytes(item_data)?;
101 decoded_data.push(item);
102 } else {
103 return Err("Buffer is too short for item length".into());
104 }
105 }
106
107 Ok(decoded_data)
108
109}
110
111pub trait IntoBytes {
112 fn into_bytes(&self) -> Vec<u8>;
113}
114
115macro_rules! impl_into_bytes_from_le_bytes {
116 ($type:ty) => {
117 impl IntoBytes for $type {
118 fn into_bytes(&self) -> Vec<u8> {
119 self.to_le_bytes().to_vec()
120 }
121 }
122
123 impl<'a> IntoBytes for &$type {
124 fn into_bytes(&self) -> Vec<u8> {
125 (*self).to_le_bytes().to_vec()
126 }
127 }
128 };
129}
130
131impl_into_bytes_from_le_bytes!(u8);
132impl_into_bytes_from_le_bytes!(u16);
133impl_into_bytes_from_le_bytes!(u32);
134impl_into_bytes_from_le_bytes!(u64);
135impl_into_bytes_from_le_bytes!(u128);
136impl_into_bytes_from_le_bytes!(i8);
137impl_into_bytes_from_le_bytes!(i16);
138impl_into_bytes_from_le_bytes!(i32);
139impl_into_bytes_from_le_bytes!(i64);
140impl_into_bytes_from_le_bytes!(i128);
141
142macro_rules! impl_into_bytes_from_as_bytes {
143 ($type:ty) => {
144 impl IntoBytes for $type {
145 fn into_bytes(&self) -> Vec<u8> {
146 self.as_bytes().to_vec()
147 }
148 }
149
150 impl<'a> IntoBytes for &$type {
151 fn into_bytes(&self) -> Vec<u8> {
152 (*self).as_bytes().to_vec()
153 }
154 }
155 };
156}
157
158impl_into_bytes_from_as_bytes!(String);
159impl_into_bytes_from_as_bytes!(str);
160
161macro_rules! impl_into_bytes_from_to_vec {
162 ($type:ty) => {
163 impl IntoBytes for $type {
164 fn into_bytes(&self) -> Vec<u8> {
165 self.to_vec()
166 }
167 }
168
169 impl<'a> IntoBytes for &$type {
170 fn into_bytes(&self) -> Vec<u8> {
171 (*self).to_vec()
172 }
173 }
174 };
175}
176
177impl_into_bytes_from_to_vec!(Vec<u8>);
178impl_into_bytes_from_to_vec!([u8]);
179
180impl IntoBytes for char {
181 fn into_bytes(&self) -> Vec<u8> {
182 let mut buf = [0; 4];
183 self.encode_utf8(&mut buf).as_bytes().to_vec()
184 }
185}
186
187impl IntoBytes for &char {
188 fn into_bytes(&self) -> Vec<u8> {
189 let mut buf = [0; 4];
190 (*self).encode_utf8(&mut buf).as_bytes().to_vec()
191 }
192}
193
194
195
196pub trait TryFromBytes<'a>: Sized {
197 fn try_from_bytes(value: &'a [u8]) -> Result<Self, Box<dyn std::error::Error>>;
198}
199
200impl TryFromBytes<'_> for String {
201 fn try_from_bytes(value: &[u8]) -> Result<Self, Box<dyn std::error::Error>> {
202 match String::from_utf8(value.to_vec()) {
203 Ok(s) => Ok(s),
204 Err(e) => Err(Box::new(e) as Box<dyn std::error::Error>),
205 }
206 }
207}
208
209impl TryFromBytes<'_> for Vec<u8> {
210 fn try_from_bytes(value: &[u8]) -> Result<Self, Box<dyn std::error::Error>> {
211 Ok(value.to_vec())
212 }
213}
214
215impl<'a> TryFromBytes<'a> for &'a [u8] {
216 fn try_from_bytes(value: &'a [u8]) -> Result<&[u8], Box<dyn std::error::Error>> {
217 Ok(value)
218 }
219}
220
221
222
223macro_rules! impl_try_from_bytes_for_numeric {
224 ($type:ty) => {
225 impl TryFromBytes<'_> for $type {
226 fn try_from_bytes(value: &[u8]) -> Result<Self, Box<dyn std::error::Error>> {
227 if value.len() != std::mem::size_of::<Self>() {
228 return Err("Invalid byte size".into());
229 }
230 let mut array = [0u8; std::mem::size_of::<Self>()];
231 array.copy_from_slice(&value);
232 Ok(Self::from_le_bytes(array))
233 }
234 }
235 };
236}
237
238impl_try_from_bytes_for_numeric!(u8);
239impl_try_from_bytes_for_numeric!(u16);
240impl_try_from_bytes_for_numeric!(u32);
241impl_try_from_bytes_for_numeric!(u64);
242impl_try_from_bytes_for_numeric!(u128);
243impl_try_from_bytes_for_numeric!(i8);
244impl_try_from_bytes_for_numeric!(i16);
245impl_try_from_bytes_for_numeric!(i32);
246impl_try_from_bytes_for_numeric!(i64);
247impl_try_from_bytes_for_numeric!(i128);
248
249impl TryFromBytes<'_> for char {
250 fn try_from_bytes(value: &[u8]) -> Result<Self, Box<dyn std::error::Error>> {
251 let str_slice = std::str::from_utf8(value)
252 .map_err(|e| Box::new(e) as Box<dyn std::error::Error>)?;
253
254 let mut char_iter = str_slice.chars();
255 if let (Some(ch), None) = (char_iter.next(), char_iter.next()) {
256 Ok(ch)
257 } else {
258 Err("Invalid byte slice for char".into())
259 }
260 }
261}
262
263
264#[cfg(test)]
265mod tests {
266 use super::*;
267
268 #[test]
269 fn list_of_one() {
270
271 let list = vec![vec![1, 2, 3]];
272
273 let encoded = encode(&list).unwrap();
274
275 let decoded: Vec<Vec<u8>> = decode(&encoded).unwrap();
276
277 assert_eq!(list, decoded);
278
279 }
280
281 #[test]
282 fn three_arrays() {
283
284 let list: Vec<&[u8]> = vec![&[1,2,3], &[4,5,6], &[7,8,9]];
285
286 let encoded = encode(list.clone()).unwrap();
287
288 let exp_encoded = vec![1,3,1,2,3,1,3,4,5,6,1,3,7,8,9];
289
290 assert_eq!(exp_encoded, encoded);
291
292 let decoded: Vec<&[u8]> = decode(&encoded).unwrap();
293
294 assert_eq!(list, decoded);
295
296 }
297
298 #[test]
299 fn list_of_none() {
300
301 let list: Vec<u8> = vec![];
302
303 let encoded = encode(&list).unwrap();
304
305 assert_eq!(list, decode(&encoded).unwrap());
306
307 }
308
309 #[test]
310 fn list_of_one_empty() {
311
312 let list: Vec<Vec<u8>> = vec![vec![]];
313
314 let encoded = encode(&list).unwrap();
315
316 let decoded: Vec<Vec<u8>> = decode(&encoded).unwrap();
317
318 assert_eq!(list, decoded);
319
320 }
321
322 #[test]
323 fn list_of_three_empty() {
324
325 let list: Vec<&[u8]> = vec![&[], &[], &[]];
326
327 let encoded = encode(list.clone()).unwrap();
328
329 let decoded: Vec<&[u8]> = decode(&encoded).unwrap();
330
331 assert_eq!(list, decoded);
332
333 }
334
335 #[test]
336 fn list_of_two_and_one_empty() {
337
338 let list: Vec<&[u8]> = vec![&[1,2,3], &[], &[7,8,9]];
339
340 let encoded = encode(list.clone()).unwrap();
341
342 let decoded: Vec<&[u8]> = decode(&encoded).unwrap();
343
344 assert_eq!(list, decoded);
345
346 }
347
348 #[test]
349 fn test_char_into_bytes() {
350 let value = 'a'; assert_eq!(value.into_bytes(), vec![97]);
352
353 let value = 'ñ'; assert_eq!(value.into_bytes(), vec![195, 177]);
355 }
356
357 #[test]
358 fn test_char_try_from_bytes_valid() {
359 let bytes = [97]; assert_eq!(char::try_from_bytes(&bytes).unwrap(), 'a');
361
362 let bytes = [195, 177]; assert_eq!(char::try_from_bytes(&bytes).unwrap(), 'ñ');
364 }
365
366 #[test]
367 fn test_char_try_from_bytes_invalid() {
368 let bytes = []; assert!(char::try_from_bytes(&bytes).is_err());
370
371 let bytes = [97, 98]; assert!(char::try_from_bytes(&bytes).is_err());
373
374 let bytes = [255]; assert!(char::try_from_bytes(&bytes).is_err());
376 }
377
378
379}