rtools/
data.rs

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}