cu29_runtime/
payload.rs

1/// This module is a collection of Copper friendly data structures for message payloads.
2///
3/// The constraint on the messages is that they can be part of a copper list, fixed sized and bincode serializable.
4use arrayvec::ArrayVec;
5use bincode::{Decode, Encode};
6
7/// Copper friendly wrapper for a fixed size array.
8#[derive(Clone, Debug, Default)]
9pub struct CuArray<T, const N: usize> {
10    inner: ArrayVec<T, N>,
11}
12
13impl<T, const N: usize> CuArray<T, N> {
14    pub fn new() -> Self {
15        Self {
16            inner: ArrayVec::new(),
17        }
18    }
19
20    pub fn fill_from_iter<I>(&mut self, iter: I)
21    where
22        I: IntoIterator<Item = T>,
23    {
24        self.inner.clear(); // Clear existing data
25        for value in iter.into_iter().take(N) {
26            self.inner.push(value);
27        }
28    }
29
30    pub fn len(&self) -> usize {
31        self.inner.len()
32    }
33
34    pub fn is_empty(&self) -> bool {
35        self.inner.len() == 0
36    }
37
38    pub fn as_slice(&self) -> &[T] {
39        &self.inner
40    }
41
42    pub fn capacity(&self) -> usize {
43        N
44    }
45}
46
47impl<T, const N: usize> Encode for CuArray<T, N>
48where
49    T: Encode,
50{
51    fn encode<E: bincode::enc::Encoder>(
52        &self,
53        encoder: &mut E,
54    ) -> Result<(), bincode::error::EncodeError> {
55        // Encode the length first
56        (self.inner.len() as u32).encode(encoder)?;
57
58        // Encode elements in the `ArrayVec`
59        for elem in &self.inner {
60            elem.encode(encoder)?;
61        }
62
63        Ok(())
64    }
65}
66
67impl<T, const N: usize> Decode<()> for CuArray<T, N>
68where
69    T: Decode<()>,
70{
71    fn decode<D: bincode::de::Decoder<Context = ()>>(
72        decoder: &mut D,
73    ) -> Result<Self, bincode::error::DecodeError> {
74        // Decode the length first
75        let len = u32::decode(decoder)? as usize;
76        if len > N {
77            return Err(bincode::error::DecodeError::OtherString(format!(
78                "Decoded length {len} exceeds maximum capacity {N}"
79            )));
80        }
81
82        // Decode elements into a new `ArrayVec`
83        let mut inner = ArrayVec::new();
84        for _ in 0..len {
85            inner.push(T::decode(decoder)?);
86        }
87
88        Ok(Self { inner })
89    }
90}