t3rn_sdk_primitives/
storage.rs1use crate::Vec;
2use arrayvec::ArrayVec;
3use codec::{Compact, Decode, Encode, EncodeLike, MaxEncodedLen, Output};
4
5#[derive(scale_info::TypeInfo, Debug, Clone)]
11pub struct BoundedVec<T: Encode + Decode, const CAP: usize>(pub ArrayVec<T, CAP>);
12
13impl<T, const CAP: usize> FromIterator<T> for BoundedVec<T, CAP>
14where
15 T: Encode + Decode,
16{
17 fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {
18 let inner = ArrayVec::from_iter(iter);
19 Self(inner)
20 }
21}
22
23impl<T, const CAP: usize> Default for BoundedVec<T, CAP>
24where
25 T: Encode + Decode,
26{
27 fn default() -> Self {
28 Self(ArrayVec::new())
29 }
30}
31
32impl<T, const CAP: usize> MaxEncodedLen for BoundedVec<T, CAP>
33where
34 T: MaxEncodedLen + Encode + Decode,
35{
36 fn max_encoded_len() -> usize {
37 Compact(CAP as u32)
38 .encoded_size()
39 .saturating_add(CAP.saturating_mul(T::max_encoded_len()))
40 }
41}
42
43impl<T, const CAP: usize> scale_info::prelude::ops::Deref for BoundedVec<T, CAP>
44where
45 T: Decode + Encode,
46{
47 type Target = [T];
48
49 fn deref(&self) -> &Self::Target {
50 &self.0
51 }
52}
53
54impl<T: Decode + Encode, const CAP: usize> Decode for BoundedVec<T, CAP> {
55 fn decode<I: codec::Input>(input: &mut I) -> Result<Self, codec::Error> {
56 let inner = Vec::<T>::decode(input)?;
57 if inner.len() > CAP {
58 return Err("BoundedVec exceeds its limit".into())
59 }
60 let inner = ArrayVec::from_iter(inner);
61 Ok(Self(inner))
62 }
63
64 fn skip<I: codec::Input>(input: &mut I) -> Result<(), codec::Error> {
65 Vec::<T>::skip(input)
66 }
67}
68
69impl<T: Decode + Encode, const CAP: usize> Encode for BoundedVec<T, CAP> {
70 fn size_hint(&self) -> usize {
71 self.0.iter().map(|x| x.size_hint()).sum()
72 }
73
74 fn encode_to<W: Output + ?Sized>(&self, dest: &mut W) {
75 let bits = self.0.len();
76 Compact(bits as u32).encode_to(dest);
77 self.0.iter().for_each(|x| x.encode_to(dest));
78 }
79}
80
81impl<T: Encode + Decode, const CAP: usize> EncodeLike<Vec<T>> for BoundedVec<T, CAP> {}
83
84#[cfg(test)]
85mod tests {
86 use super::*;
87
88 #[test]
89 fn test_boundec_vec_options() {
90 let x = BoundedVec::<_, 3>::from_iter(vec![Some(1_u8), Some(2_u8), Some(3_u8)]);
91 assert_eq!(x.encode(), vec![12, 1, 1, 1, 2, 1, 3]);
92 }
93}