cml_crypto/typed_bytes/
mod.rs

1mod builder;
2
3pub use builder::ByteBuilder;
4use std::marker::PhantomData;
5
6/// A typed slice of bytes
7#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
8pub struct ByteSlice<'a, T> {
9    slice: &'a [u8],
10    phantom: PhantomData<T>,
11}
12
13/// A typed Array of bytes
14#[derive(Debug, Clone, PartialEq, Eq, Hash)]
15pub struct ByteArray<T: ?Sized> {
16    array: Box<[u8]>,
17    phantom: PhantomData<T>,
18}
19
20impl<T> AsRef<[u8]> for ByteArray<T> {
21    fn as_ref(&self) -> &[u8] {
22        self.as_slice()
23    }
24}
25
26impl<'a, T> AsRef<[u8]> for ByteSlice<'a, T> {
27    fn as_ref(&self) -> &[u8] {
28        self.as_slice()
29    }
30}
31
32impl<T> ByteArray<T> {
33    pub fn as_byteslice(&self) -> ByteSlice<'_, T> {
34        ByteSlice {
35            slice: &self.array[..],
36            phantom: self.phantom,
37        }
38    }
39    pub fn as_slice(&self) -> &[u8] {
40        &self.array[..]
41    }
42
43    fn from_vec(v: Vec<u8>) -> Self {
44        ByteArray {
45            array: v.into(),
46            phantom: PhantomData,
47        }
48    }
49}
50
51impl<T> From<Vec<u8>> for ByteArray<T> {
52    fn from(v: Vec<u8>) -> Self {
53        ByteArray::from_vec(v)
54    }
55}
56
57impl<'a, T> ByteSlice<'a, T> {
58    pub fn as_slice(&self) -> &[u8] {
59        self.slice
60    }
61
62    fn sub_byteslice<U>(&'a self, start: usize, size: usize) -> ByteSlice<'a, U> {
63        ByteSlice {
64            slice: &self.slice[start..start + size],
65            phantom: PhantomData,
66        }
67    }
68}
69
70pub trait ByteAccessor<A> {
71    const START_SIZE: (usize, usize);
72}
73
74impl<T> ByteArray<T> {
75    pub fn sub<U>(&self) -> ByteSlice<'_, U>
76    where
77        T: ByteAccessor<U>,
78    {
79        let (start, size) = <T as ByteAccessor<U>>::START_SIZE;
80        ByteSlice {
81            slice: &self.array[start..start + size],
82            phantom: PhantomData,
83        }
84    }
85}
86
87impl<'a, T> ByteSlice<'a, T> {
88    pub fn sub<U>(&'a self) -> ByteSlice<'a, U>
89    where
90        T: ByteAccessor<U>,
91    {
92        let (start, sz) = <T as ByteAccessor<U>>::START_SIZE;
93        self.sub_byteslice(start, sz)
94    }
95}
96
97#[cfg(test)]
98mod tests {
99    use super::*;
100
101    pub struct Big;
102    pub struct Little;
103
104    impl ByteAccessor<Little> for Big {
105        const START_SIZE: (usize, usize) = (2, 3);
106    }
107
108    #[test]
109    pub fn typed_accessor() {
110        let v: Vec<u8> = vec![0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
111        let b: ByteArray<Big> = v.into();
112        assert_eq!(b.sub::<Little>().as_slice(), [2, 3, 4])
113    }
114}