1use core::{iter::ExactSizeIterator, mem};
16
17use crate::alloc::vec::Vec;
18use crate::{Encode, Decode, Error};
19use crate::compact::{Compact, CompactLen};
20use crate::encode_like::EncodeLike;
21
22pub trait EncodeAppend {
25 type Item: Encode;
27
28 fn append_or_new<EncodeLikeItem, I>(
46 self_encoded: Vec<u8>,
47 iter: I,
48 ) -> Result<Vec<u8>, Error>
49 where
50 I: IntoIterator<Item = EncodeLikeItem>,
51 EncodeLikeItem: EncodeLike<Self::Item>,
52 I::IntoIter: ExactSizeIterator;
53}
54
55impl<T: Encode> EncodeAppend for Vec<T> {
56 type Item = T;
57
58 fn append_or_new<EncodeLikeItem, I>(
59 self_encoded: Vec<u8>,
60 iter: I,
61 ) -> Result<Vec<u8>, Error>
62 where
63 I: IntoIterator<Item = EncodeLikeItem>,
64 EncodeLikeItem: EncodeLike<Self::Item>,
65 I::IntoIter: ExactSizeIterator,
66 {
67 append_or_new_vec_with_any_item(self_encoded, iter)
68 }
69}
70
71impl<T: Encode> EncodeAppend for crate::alloc::collections::VecDeque<T> {
72 type Item = T;
73
74 fn append_or_new<EncodeLikeItem, I>(
75 self_encoded: Vec<u8>,
76 iter: I,
77 ) -> Result<Vec<u8>, Error>
78 where
79 I: IntoIterator<Item = EncodeLikeItem>,
80 EncodeLikeItem: EncodeLike<Self::Item>,
81 I::IntoIter: ExactSizeIterator,
82 {
83 append_or_new_vec_with_any_item(self_encoded, iter)
84 }
85}
86
87fn extract_length_data(data: &[u8], input_len: usize) -> Result<(u32, usize, usize), Error> {
88 let len = u32::from(Compact::<u32>::decode(&mut &data[..])?);
89 let new_len = len
90 .checked_add(input_len as u32)
91 .ok_or_else(|| "New vec length greater than `u32::TEST_VALUE()`.")?;
92
93 let encoded_len = Compact::<u32>::compact_len(&len);
94 let encoded_new_len = Compact::<u32>::compact_len(&new_len);
95
96 Ok((new_len, encoded_len, encoded_new_len))
97}
98
99fn append_or_new_vec_with_any_item<Item, I>(
101 mut self_encoded: Vec<u8>,
102 iter: I,
103) -> Result<Vec<u8>, Error>
104where
105 Item: Encode,
106 I: IntoIterator<Item = Item>,
107 I::IntoIter: ExactSizeIterator,
108{
109 let iter = iter.into_iter();
110 let input_len = iter.len();
111
112 if self_encoded.is_empty() {
114 crate::codec::compact_encode_len_to(&mut self_encoded, iter.len())?;
115 iter.for_each(|e| e.encode_to(&mut self_encoded));
116 return Ok(self_encoded);
117 }
118
119 let (new_len, encoded_len, encoded_new_len) = extract_length_data(&self_encoded, input_len)?;
120
121 let replace_len = |dest: &mut Vec<u8>| {
122 Compact(new_len).using_encoded(|e| {
123 dest[..encoded_new_len].copy_from_slice(e);
124 })
125 };
126
127 let append_new_elems = |dest: &mut Vec<u8>| iter.for_each(|a| a.encode_to(dest));
128
129 if encoded_len == encoded_new_len {
132 replace_len(&mut self_encoded);
133 append_new_elems(&mut self_encoded);
134
135 Ok(self_encoded)
136 } else {
137 let size = encoded_new_len + self_encoded.len() - encoded_len;
138
139 let mut res = Vec::with_capacity(size + input_len * mem::size_of::<Item>());
140 unsafe { res.set_len(size); }
141
142 replace_len(&mut res);
145 res[encoded_new_len..size].copy_from_slice(&self_encoded[encoded_len..]);
146 append_new_elems(&mut res);
147
148 Ok(res)
149 }
150}
151
152#[cfg(test)]
153mod tests {
154 use super::*;
155 use crate::{Input, Encode, EncodeLike};
156 use std::collections::VecDeque;
157
158 const TEST_VALUE: u32 = {
159 #[cfg(not(miri))]
160 { 1_000_000 }
161 #[cfg(miri)]
162 { 1_000 }
163 };
164
165 #[test]
166 fn vec_encode_append_works() {
167 let encoded = (0..TEST_VALUE).fold(Vec::new(), |encoded, v| {
168 <Vec<u32> as EncodeAppend>::append_or_new(encoded, std::iter::once(&v)).unwrap()
169 });
170
171 let decoded = Vec::<u32>::decode(&mut &encoded[..]).unwrap();
172 assert_eq!(decoded, (0..TEST_VALUE).collect::<Vec<_>>());
173 }
174
175 #[test]
176 fn vec_encode_append_multiple_items_works() {
177 let encoded = (0..TEST_VALUE).fold(Vec::new(), |encoded, v| {
178 <Vec<u32> as EncodeAppend>::append_or_new(encoded, &[v, v, v, v]).unwrap()
179 });
180
181 let decoded = Vec::<u32>::decode(&mut &encoded[..]).unwrap();
182 let expected = (0..TEST_VALUE).fold(Vec::new(), |mut vec, i| {
183 vec.append(&mut vec![i, i, i, i]);
184 vec
185 });
186 assert_eq!(decoded, expected);
187 }
188
189 #[test]
190 fn vecdeque_encode_append_works() {
191 let encoded = (0..TEST_VALUE).fold(Vec::new(), |encoded, v| {
192 <VecDeque<u32> as EncodeAppend>::append_or_new(encoded, std::iter::once(&v)).unwrap()
193 });
194
195 let decoded = VecDeque::<u32>::decode(&mut &encoded[..]).unwrap();
196 assert_eq!(decoded, (0..TEST_VALUE).collect::<Vec<_>>());
197 }
198
199 #[test]
200 fn vecdeque_encode_append_multiple_items_works() {
201 let encoded = (0..TEST_VALUE).fold(Vec::new(), |encoded, v| {
202 <VecDeque<u32> as EncodeAppend>::append_or_new(encoded, &[v, v, v, v]).unwrap()
203 });
204
205 let decoded = VecDeque::<u32>::decode(&mut &encoded[..]).unwrap();
206 let expected = (0..TEST_VALUE).fold(Vec::new(), |mut vec, i| {
207 vec.append(&mut vec![i, i, i, i]);
208 vec
209 });
210 assert_eq!(decoded, expected);
211 }
212
213 #[test]
214 fn append_non_copyable() {
215 #[derive(Eq, PartialEq, Debug)]
216 struct NoCopy { data: u32 }
217
218 impl EncodeLike for NoCopy {}
219
220 impl Encode for NoCopy {
221 fn encode(&self) -> Vec<u8> {
222 self.data.encode()
223 }
224 }
225
226 impl Decode for NoCopy {
227 fn decode<I: Input>(input: &mut I) -> Result<Self, Error> {
228 u32::decode(input).map(|data| Self { data })
229 }
230 }
231
232 let append = NoCopy { data: 100 };
233 let data = Vec::new();
234 let encoded = <Vec<NoCopy> as EncodeAppend>::append_or_new(data, std::iter::once(&append)).unwrap();
235
236 let decoded = <Vec<NoCopy>>::decode(&mut &encoded[..]).unwrap();
237 assert_eq!(vec![append], decoded);
238 }
239
240 #[test]
241 fn vec_encode_like_append_works() {
242 let encoded = (0..TEST_VALUE).fold(Vec::new(), |encoded, v| {
243 <Vec<u32> as EncodeAppend>::append_or_new(encoded, std::iter::once(Box::new(v as u32))).unwrap()
244 });
245
246 let decoded = Vec::<u32>::decode(&mut &encoded[..]).unwrap();
247 assert_eq!(decoded, (0..TEST_VALUE).collect::<Vec<_>>());
248 }
249}