smart_keymap/
slice.rs

1use core::mem::MaybeUninit;
2
3use serde::Deserialize;
4
5/// A helper value type for Copy-able slices.
6#[derive(Debug, Clone, Copy, Deserialize)]
7#[serde(from = "heapless::Vec<T, N>")]
8pub struct Slice<T: Copy, const N: usize> {
9    len: usize,
10    data: [MaybeUninit<T>; N],
11}
12
13impl<T: Copy, const N: usize> Slice<T, N> {
14    /// Constructs [Slice] from a slice of items.
15    pub const fn from_slice(slice: &[T]) -> Self {
16        let mut data = [const { MaybeUninit::uninit() }; N];
17        if slice.len() > N {
18            panic!("Slice length exceeds the maximum size for N");
19        }
20        let mut i = 0;
21        let len = slice.len();
22        while i < len {
23            let item = slice[i];
24            data[i] = MaybeUninit::new(item);
25            i += 1;
26        }
27        Slice { len, data }
28    }
29
30    /// A slice representation of the data.
31    pub const fn as_slice(&self) -> &[T] {
32        unsafe { core::slice::from_raw_parts(self.data.as_ptr() as *const T, self.len) }
33    }
34}
35
36impl<T: Copy, const N: usize> core::ops::Deref for Slice<T, N> {
37    type Target = [T];
38
39    fn deref(&self) -> &Self::Target {
40        self.as_slice()
41    }
42}
43
44impl<T: Copy + PartialEq, const N: usize> core::cmp::PartialEq for Slice<T, N> {
45    fn eq(&self, other: &Self) -> bool {
46        self.as_slice() == other.as_slice()
47    }
48}
49
50impl<T: Copy, const N: usize> core::convert::From<&[T]> for Slice<T, N> {
51    fn from(slice: &[T]) -> Self {
52        Self::from_slice(slice)
53    }
54}
55
56impl<T: Copy, const N: usize> core::convert::From<heapless::Vec<T, N>> for Slice<T, N> {
57    fn from(v: heapless::Vec<T, N>) -> Self {
58        Self::from_slice(v.as_slice())
59    }
60}
61
62#[cfg(test)]
63mod tests {
64    use super::*;
65
66    #[test]
67    fn test_slice_as_slice_equals() {
68        const N: usize = 5;
69        type S = Slice<u8, N>;
70        let expected: &[u8] = &[1, 2];
71        let s: S = Slice::from_slice(expected);
72
73        assert_eq!(expected, s.as_slice());
74    }
75}