1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
//! This module contains the GetBytes trait.

/// This trait is used for casting types to bytes safely. Creating a BitTree requires that the
/// key and value types implement this trait to make sure that the bits for a type can be accurately
/// retrieved.
pub trait GetBytes: Sized + Clone {
    fn get_bytes(&self) -> &[u8] {
        unsafe {
            core::slice::from_raw_parts(self as *const Self as *const u8, core::mem::size_of::<Self>())
        }
    }
}

impl GetBytes for u8 {}
impl GetBytes for u16 {}
impl GetBytes for u32 {}
impl GetBytes for u64 {}
impl GetBytes for usize {}
impl GetBytes for i8 {}
impl GetBytes for i16 {}
impl GetBytes for i32 {}
impl GetBytes for i64 {}
impl GetBytes for isize {}
impl GetBytes for char {}
impl GetBytes for bool {}
impl<'a> GetBytes for &'a str {
    fn get_bytes(&self) -> &[u8] {
        self.chars().map(|x| x.get_bytes().to_vec()).flatten().collect::<alloc::vec::Vec<u8>>().leak()
    }
}

impl<T: GetBytes> GetBytes for &T {
    fn get_bytes(&self) -> &[u8] {
        unsafe {
            core::slice::from_raw_parts(*self as *const T as *const u8, core::mem::size_of::<T>())
        }
    }
}

impl<T: GetBytes> GetBytes for Option<T> {
    fn get_bytes(&self) -> &[u8] {
        let mut out = alloc::vec![self.is_some() as u8];
        if self.is_some() {
            out.extend_from_slice(self.as_ref().unwrap().get_bytes());
        }
        out.leak()
    }
}

impl<'a, T: GetBytes> GetBytes for &'a [T] {
    fn get_bytes(&self) -> &[u8] {
        let mut out = alloc::vec::Vec::new();
        for x in self.iter() {
            out.extend_from_slice(x.get_bytes());
        }
        out.leak()
    }
}

impl<T: GetBytes> GetBytes for alloc::vec::Vec<T> {
    fn get_bytes(&self) -> &[u8] {
        let mut out = alloc::vec::Vec::new();
        for x in self.iter() {
            out.extend_from_slice(x.get_bytes());
        }
        out.leak()
    }
}

impl GetBytes for alloc::string::String {
    fn get_bytes(&self) -> &[u8] {
        let mut out = alloc::vec::Vec::new();
        for x in self.chars() {
            out.extend_from_slice(x.get_bytes());
        }
        out.leak()
    }
}

use super::BitTree;
impl<K: GetBytes, V: GetBytes> GetBytes for BitTree<K, V> {
    fn get_bytes(&self) -> &[u8] {
        let mut out = alloc::vec::Vec::new();
        out.extend_from_slice(self.is_keys.get_bytes());
        out.extend_from_slice(self.value.get_bytes());
        unsafe {
            out.extend_from_slice(self.next[0].map(|x| &*x).get_bytes());
            out.extend_from_slice(self.next[1].map(|x| &*x).get_bytes());
        }
        out.leak()
    }
}