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