1use std::{
2 borrow::BorrowMut,
3 mem::{size_of, zeroed},
4};
5
6pub fn to_data<Result: Copy, T>(value: T) -> Vec<Result> {
7 let ptr: *const Result = std::ptr::from_ref::<T>(&value).cast::<Result>();
8 let mut result = vec![];
9
10 let size = size_of::<T>() / size_of::<Result>();
11
12 for i in 0..size {
13 result.push(unsafe { *ptr.add(i) });
14 }
15
16 result
17}
18
19pub fn to_bytes<T>(val: T) -> Vec<u8> {
20 to_data(val)
21}
22
23pub fn from_bytes<T>(bytes: &[u8]) -> T {
24 if bytes.len() != size_of::<T>() {
25 panic!();
26 }
27
28 let mut val: T = unsafe { zeroed() };
29 let mut ptr = std::ptr::from_mut::<T>(val.borrow_mut()).cast::<u8>();
30
31 for byte in bytes {
32 unsafe {
33 *ptr = *byte;
34 ptr = ptr.add(1);
35 }
36 }
37
38 val
39}
40
41#[cfg(test)]
42mod test {
43 use crate::data::{from_bytes, to_bytes, to_data};
44
45 #[test]
46 fn test() {
47 #[allow(dead_code)]
48 #[derive(PartialEq, Debug, Clone)]
49 struct A {
50 a: u8,
51 b: u8,
52 c: u8,
53 }
54
55 let a = A { a: 10, b: 20, c: 30 };
56
57 let bytes = to_bytes(a.clone());
58
59 assert_eq!(vec![10, 20, 30], bytes);
60
61 let from = from_bytes::<A>(&bytes);
62
63 assert_eq!(from, a);
64 }
65
66 #[test]
67 fn to_data_test() {
68 #[allow(dead_code)]
69 struct A {
70 a: u32,
71 b: u32,
72 c: u32,
73 }
74
75 let a = A { a: 10, b: 20, c: 30 };
76
77 let data: Vec<u32> = to_data(a);
78
79 assert_eq!(data, [10, 20, 30]);
80
81 #[allow(dead_code)]
82 struct B {
83 a: u8,
84 b: u8,
85 c: u8,
86 }
87
88 let b = B { a: 10, b: 20, c: 30 };
89
90 let data: Vec<u8> = to_data(b);
91
92 assert_eq!(data, [10, 20, 30]);
93 }
94
95 #[test]
96 #[should_panic]
97 fn wrong_size() {
98 _ = from_bytes::<u8>(&[1, 2, 3, 4])
99 }
100}