1use crate::{BufsMut, EncodeSize, Error, RangeCfg, Read, Write};
7#[cfg(not(feature = "std"))]
8use alloc::vec::Vec;
9use bytes::{Buf, BufMut};
10
11impl<T: Write> Write for Vec<T> {
12 #[inline]
13 fn write(&self, buf: &mut impl BufMut) {
14 self.as_slice().write(buf)
15 }
16
17 #[inline]
18 fn write_bufs(&self, buf: &mut impl BufsMut) {
19 self.as_slice().write_bufs(buf)
20 }
21}
22
23impl<T: EncodeSize> EncodeSize for Vec<T> {
24 #[inline]
25 fn encode_size(&self) -> usize {
26 self.as_slice().encode_size()
27 }
28
29 #[inline]
30 fn encode_inline_size(&self) -> usize {
31 self.as_slice().encode_inline_size()
32 }
33}
34
35impl<T: Write> Write for &[T] {
36 #[inline]
37 fn write(&self, buf: &mut impl BufMut) {
38 self.len().write(buf);
39 T::write_slice(self, buf);
40 }
41
42 #[inline]
43 fn write_bufs(&self, buf: &mut impl BufsMut) {
44 self.len().write(buf);
45 T::write_slice_bufs(self, buf);
46 }
47}
48
49impl<T: EncodeSize> EncodeSize for &[T] {
50 #[inline]
51 fn encode_size(&self) -> usize {
52 self.len().encode_size() + T::encode_size_slice(self)
53 }
54
55 #[inline]
56 fn encode_inline_size(&self) -> usize {
57 self.len().encode_size() + T::encode_inline_size_slice(self)
58 }
59}
60
61impl<T: Read> Read for Vec<T> {
62 type Cfg = (RangeCfg<usize>, T::Cfg);
63
64 #[inline]
65 fn read_cfg(buf: &mut impl Buf, (range, cfg): &Self::Cfg) -> Result<Self, Error> {
66 let len = usize::read_cfg(buf, range)?;
67 T::read_vec(buf, len, cfg)
68 }
69}
70
71#[cfg(test)]
72mod tests {
73 use super::*;
74 use crate::{
75 types::tests::{Byte, TrackingReadBuf, TrackingWriteBuf},
76 DecodeRangeExt, Encode,
77 };
78 use bytes::{Bytes, BytesMut};
79
80 #[test]
81 fn test_vec() {
82 let vec_values = [vec![], vec![1u8], vec![1u8, 2u8, 3u8]];
83 for value in vec_values {
84 let encoded = value.encode();
85 assert_eq!(encoded.len(), value.len() * core::mem::size_of::<u8>() + 1);
86
87 let len = value.len();
89 let decoded = Vec::<u8>::decode_range(encoded, len..=len).unwrap();
90 assert_eq!(value, decoded);
91
92 assert!(matches!(
94 Vec::<u8>::decode_range(value.encode(), 0..len),
95 Err(Error::InvalidLength(_))
96 ));
97
98 assert!(matches!(
100 Vec::<u8>::decode_range(value.encode(), len + 1..),
101 Err(Error::InvalidLength(_))
102 ));
103 }
104
105 assert!(matches!(
107 Vec::<u8>::decode_range([0x02, 0x01].as_slice(), ..),
108 Err(Error::EndOfBuffer)
109 ));
110 assert!(matches!(
111 Vec::<Byte>::decode_range([0x02, 0x01].as_slice(), ..),
112 Err(Error::EndOfBuffer)
113 ));
114
115 assert!(matches!(
118 Vec::<u8>::decode_range([0x02, 0x01, 0x02, 0x03].as_slice(), ..),
119 Err(Error::ExtraData(1))
120 ));
121 assert!(matches!(
122 Vec::<Byte>::decode_range([0x02, 0x01, 0x02, 0x03].as_slice(), ..),
123 Err(Error::ExtraData(1))
124 ));
125 }
126
127 #[test]
128 fn test_slice() {
129 let slice_values: [&[u8]; 3] =
130 [[].as_slice(), [1u8].as_slice(), [1u8, 2u8, 3u8].as_slice()];
131 for value in slice_values {
132 let encoded = value.encode();
133 assert_eq!(encoded.len(), core::mem::size_of_val(value) + 1);
134
135 let len = value.len();
137 let decoded = Vec::<u8>::decode_range(encoded, len..=len).unwrap();
138 assert_eq!(value, decoded);
139
140 assert!(matches!(
142 Vec::<u8>::decode_range(value.encode(), 0..len),
143 Err(Error::InvalidLength(_))
144 ));
145
146 assert!(matches!(
148 Vec::<u8>::decode_range(value.encode(), len + 1..),
149 Err(Error::InvalidLength(_))
150 ));
151 }
152 }
153
154 #[test]
155 fn test_specialization_selection() {
156 let mut buf = TrackingWriteBuf::new();
158 vec![1u8, 2, 3].write(&mut buf);
159 assert_eq!(buf.put_slice_calls, 1);
160 assert_eq!(buf.put_u8_calls, 1);
161
162 let mut buf = TrackingWriteBuf::new();
164 vec![Byte(1), Byte(2), Byte(3)].write(&mut buf);
165 assert_eq!(buf.put_slice_calls, 0);
166 assert_eq!(buf.put_u8_calls, 4);
167
168 let values = [1u8, 2, 3];
170 let mut buf = TrackingWriteBuf::new();
171 values.as_slice().write(&mut buf);
172 assert_eq!(buf.put_slice_calls, 1);
173 assert_eq!(buf.put_u8_calls, 1);
174
175 let values = [Byte(1), Byte(2), Byte(3)];
177 let mut buf = TrackingWriteBuf::new();
178 values.as_slice().write(&mut buf);
179 assert_eq!(buf.put_slice_calls, 0);
180 assert_eq!(buf.put_u8_calls, 4);
181
182 let mut buf = TrackingWriteBuf::new();
184 vec![1u8, 2, 3].write_bufs(&mut buf);
185 assert_eq!(buf.put_slice_calls, 1);
186 assert_eq!(buf.put_u8_calls, 1);
187
188 let mut buf = TrackingWriteBuf::new();
190 vec![Byte(1), Byte(2), Byte(3)].write_bufs(&mut buf);
191 assert_eq!(buf.put_slice_calls, 0);
192 assert_eq!(buf.put_u8_calls, 4);
193
194 let mut buf = TrackingReadBuf::new(&[0x03, 0x01, 0x02, 0x03]);
196 let value = Vec::<u8>::read_cfg(&mut buf, &((..).into(), ())).unwrap();
197 assert_eq!(value, vec![1, 2, 3]);
198 assert_eq!(buf.copy_to_slice_calls, 1);
199 assert_eq!(buf.get_u8_calls, 1);
200
201 let mut buf = TrackingReadBuf::new(&[0x03, 0x01, 0x02, 0x03]);
203 let value = Vec::<Byte>::read_cfg(&mut buf, &((..).into(), ())).unwrap();
204 assert_eq!(value, vec![Byte(1), Byte(2), Byte(3)]);
205 assert_eq!(buf.copy_to_slice_calls, 0);
206 assert_eq!(buf.get_u8_calls, 4);
207 }
208
209 #[test]
210 fn test_write_bufs_equivalence() {
211 fn assert_equivalent<T: Write>(value: &T) {
212 let mut write = BytesMut::new();
213 value.write(&mut write);
214
215 let mut write_bufs = TrackingWriteBuf::new();
216 value.write_bufs(&mut write_bufs);
217
218 assert_eq!(write.freeze(), write_bufs.freeze());
219 }
220
221 assert_equivalent(&vec![1u8, 2, 3]);
222 assert_equivalent(&vec![0x0102u16, 0x0304, 0x0506]);
223 assert_equivalent(&vec![Byte(1), Byte(2), Byte(3)]);
224 assert_equivalent(&vec![
225 Bytes::from_static(&[1u8, 2, 3]),
226 Bytes::from_static(&[4u8, 5, 6]),
227 ]);
228
229 let values = [1u8, 2, 3];
230 assert_equivalent(&values.as_slice());
231
232 let values = [0x0102u16, 0x0304, 0x0506];
233 assert_equivalent(&values.as_slice());
234
235 let values = [Byte(1), Byte(2), Byte(3)];
236 assert_equivalent(&values.as_slice());
237
238 let values = [
239 Bytes::from_static(&[1u8, 2, 3]),
240 Bytes::from_static(&[4u8, 5, 6]),
241 ];
242 assert_equivalent(&values.as_slice());
243 }
244
245 #[test]
246 fn test_conformity() {
247 assert_eq!(Vec::<u8>::new().encode(), &[0x00][..]);
248 assert_eq!(
249 vec![0x01u8, 0x02u8, 0x03u8].encode(),
250 &[0x03, 0x01, 0x02, 0x03][..]
251 );
252
253 let v_u16: Vec<u16> = vec![0x1234, 0xABCD];
254 assert_eq!(v_u16.encode(), &[0x02, 0x12, 0x34, 0xAB, 0xCD][..]);
255
256 let v_bool: Vec<bool> = vec![true, false, true];
257 assert_eq!(v_bool.encode(), &[0x03, 0x01, 0x00, 0x01][..]);
258
259 let v_empty_u32: Vec<u32> = Vec::new();
260 assert_eq!(v_empty_u32.encode(), &[0x00][..]);
261
262 let v_long_u8: Vec<u8> = vec![0xCC; 200]; let mut expected_long_u8 = vec![0xC8, 0x01];
265 expected_long_u8.extend_from_slice(&[0xCC; 200]);
266 assert_eq!(v_long_u8.encode(), expected_long_u8.as_slice());
267 }
268
269 #[cfg(feature = "arbitrary")]
270 mod conformance {
271 use crate::conformance::CodecConformance;
272
273 commonware_conformance::conformance_tests! {
274 CodecConformance<Vec<u8>>,
275 CodecConformance<Vec<u16>>,
276 CodecConformance<Vec<u32>>,
277 }
278 }
279}