mina_p2p_messages/
array.rs1use binprot::{BinProtRead, BinProtWrite, Nat0};
2use malloc_size_of_derive::MallocSizeOf;
3use rsexp::OfSexp;
4use serde::{Deserialize, Serialize};
5use std::ops::Deref;
6
7#[derive(
10 Clone,
11 Debug,
12 PartialEq,
13 Eq,
14 PartialOrd,
15 Ord,
16 Serialize,
17 Deserialize,
18 derive_more::From,
19 derive_more::Into,
20 MallocSizeOf,
21)]
22pub struct ArrayN<T, const N: u64>(Vec<T>);
23
24impl<T, const N: u64> AsRef<[T]> for ArrayN<T, N> {
25 fn as_ref(&self) -> &[T] {
26 self.0.as_ref()
27 }
28}
29
30impl<T, const N: u64> Deref for ArrayN<T, N> {
31 type Target = [T];
32
33 fn deref(&self) -> &Self::Target {
34 self.0.as_ref()
35 }
36}
37
38impl<T, const N: u64> IntoIterator for ArrayN<T, N> {
39 type Item = T;
40
41 type IntoIter = <Vec<T> as IntoIterator>::IntoIter;
42
43 fn into_iter(self) -> Self::IntoIter {
44 self.0.into_iter()
45 }
46}
47
48impl<'a, T, const N: u64> IntoIterator for &'a ArrayN<T, N> {
49 type Item = &'a T;
50
51 type IntoIter = <&'a Vec<T> as IntoIterator>::IntoIter;
52
53 fn into_iter(self) -> Self::IntoIter {
54 self.0.iter()
55 }
56}
57
58impl<T, const N: u64> FromIterator<T> for ArrayN<T, N> {
59 fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {
60 ArrayN::<_, N>(Vec::from_iter(iter))
61 }
62}
63
64impl<T, const N: u64> ArrayN<T, N> {
65 pub fn to_inner(self) -> Vec<T> {
66 self.0
67 }
68
69 pub fn inner(&self) -> &Vec<T> {
70 &self.0
71 }
72
73 pub fn inner_mut(&mut self) -> &mut Vec<T> {
74 &mut self.0
75 }
76
77 pub fn iter(&self) -> std::slice::Iter<'_, T> {
78 self.0.iter()
79 }
80}
81
82impl<T: OfSexp, const N: u64> OfSexp for ArrayN<T, N> {
83 fn of_sexp(s: &rsexp::Sexp) -> Result<Self, rsexp::IntoSexpError>
84 where
85 Self: Sized,
86 {
87 let limit = N as usize;
88 let elts = s.extract_list("ArrayN")?;
89
90 if elts.len() > limit {
91 return Err(rsexp::IntoSexpError::ListLengthMismatch {
92 type_: "ArrayN",
93 expected_len: limit,
94 list_len: elts.len(),
95 });
96 }
97
98 let mut converted = Vec::with_capacity(elts.len());
99 for elt in elts.iter() {
100 converted.push(rsexp::OfSexp::of_sexp(elt)?);
101 }
102
103 Ok(ArrayN(converted))
104 }
105}
106
107impl<T: rsexp::SexpOf, const N: u64> rsexp::SexpOf for ArrayN<T, N> {
108 fn sexp_of(&self) -> rsexp::Sexp {
109 let elements: Vec<rsexp::Sexp> = self.0.iter().map(|item| item.sexp_of()).collect();
110
111 rsexp::Sexp::List(elements)
112 }
113}
114
115impl<T, const N: u64> BinProtRead for ArrayN<T, N>
116where
117 T: BinProtRead,
118{
119 fn binprot_read<R: std::io::prelude::Read + ?Sized>(r: &mut R) -> Result<Self, binprot::Error> {
120 let Nat0(len) = Nat0::binprot_read(r)?;
121 if len > N {
122 return Err(MinaArrayNTooLong::<N>::new(len).into());
123 }
124 let mut v: Vec<T> = Vec::with_capacity(len as usize);
125 for _i in 0..len {
126 let item = T::binprot_read(r)?;
127 v.push(item)
128 }
129 Ok(ArrayN(v))
130 }
131}
132
133impl<T, const N: u64> BinProtWrite for ArrayN<T, N>
134where
135 T: BinProtWrite,
136{
137 fn binprot_write<W: std::io::prelude::Write>(&self, w: &mut W) -> std::io::Result<()> {
138 let len = self.0.len() as u64;
139 if len > N {
140 return Err(MinaArrayNTooLong::<N>::new(len).into());
141 }
142 Nat0(len).binprot_write(w)?;
143 for v in self.0.iter() {
144 v.binprot_write(w)?
145 }
146 Ok(())
147 }
148}
149
150#[derive(Debug, thiserror::Error)]
151#[error("String length `{0}` is greater than maximum `{N}`")]
152pub struct MinaArrayNTooLong<const N: u64>(u64);
153
154impl<const N: u64> MinaArrayNTooLong<N> {
155 fn new(actual: u64) -> Self {
156 MinaArrayNTooLong(actual)
157 }
158}
159
160impl<const N: u64> From<MinaArrayNTooLong<N>> for std::io::Error {
161 fn from(value: MinaArrayNTooLong<N>) -> Self {
162 std::io::Error::new(std::io::ErrorKind::InvalidData, Box::new(value))
163 }
164}
165
166impl<const N: u64> From<MinaArrayNTooLong<N>> for binprot::Error {
167 fn from(value: MinaArrayNTooLong<N>) -> Self {
168 binprot::Error::CustomError(Box::new(value))
169 }
170}
171
172pub type ArrayN16<T> = ArrayN<T, 16>;
174
175pub type ArrayN4000<T> = ArrayN<T, 4000>;