1use core::fmt::{self, Formatter};
7
8use alloc::{vec, vec::Vec};
9
10use crate::limited::private::LimitedVisitor;
11use derive_more::{AsMut, AsRef, Debug, Deref, DerefMut, Display, Error, Into, IntoIterator};
12use gprimitives::utils::ByteSliceFormatter;
13use parity_scale_codec::{Compact, MaxEncodedLen, decode_vec_with_len};
14use scale_decode::{
15 IntoVisitor, TypeResolver, Visitor,
16 error::ErrorKind,
17 visitor::{
18 TypeIdFor, Unexpected,
19 types::{Array, Composite, Sequence, Tuple},
20 },
21};
22use scale_encode::EncodeAsType;
23use scale_info::{
24 TypeInfo,
25 scale::{Decode, Encode},
26};
27
28#[derive(
30 Clone,
31 Default,
32 PartialEq,
33 Eq,
34 PartialOrd,
35 Ord,
36 Encode,
37 EncodeAsType,
38 Hash,
39 TypeInfo,
40 AsRef,
41 AsMut,
42 Deref,
43 DerefMut,
44 IntoIterator,
45 Into,
46)]
47#[cfg_attr(feature = "std", derive(serde::Serialize, serde::Deserialize))]
48#[as_ref(forward)]
49#[as_mut(forward)]
50#[deref(forward)]
51#[deref_mut(forward)]
52#[into_iterator(owned, ref, ref_mut)]
53pub struct LimitedVec<T, const N: usize>(Vec<T>);
54
55impl<T: Decode, const N: usize> Decode for LimitedVec<T, N> {
56 fn decode<I: parity_scale_codec::Input>(
57 input: &mut I,
58 ) -> Result<Self, parity_scale_codec::Error> {
59 let Compact(len) = <Compact<u32>>::decode(input)?;
60 let len = len as usize;
61
62 Self::validate_len(len).map_err(|e| e.as_str())?;
63
64 decode_vec_with_len(input, len).map(Self)
65 }
66}
67
68impl<T: MaxEncodedLen, const N: usize> MaxEncodedLen for LimitedVec<T, N> {
69 fn max_encoded_len() -> usize {
70 assert!(
71 N <= u32::MAX as usize,
72 "`LimitedVec<{}>` size limit is too large to be encoded",
73 N
74 );
75
76 Compact(N as u32)
77 .encoded_size()
78 .saturating_add(N * T::max_encoded_len())
79 }
80}
81
82impl<T, Resolver, const N: usize> Visitor for LimitedVisitor<LimitedVec<T, N>, Resolver>
83where
84 T: IntoVisitor,
85 Resolver: TypeResolver,
86{
87 type Value<'scale, 'resolver> = LimitedVec<T, N>;
88 type Error = scale_decode::Error;
89 type TypeResolver = Resolver;
90
91 fn visit_sequence<'scale, 'resolver>(
92 self,
93 value: &mut Sequence<'scale, 'resolver, Resolver>,
94 type_id: TypeIdFor<Self>,
95 ) -> Result<Self::Value<'scale, 'resolver>, Self::Error> {
96 if value.remaining() > N {
97 Err(scale_decode::Error::new(ErrorKind::WrongLength {
98 actual_len: value.remaining(),
99 expected_len: N,
100 }))
101 } else {
102 Vec::into_visitor()
103 .visit_sequence(value, type_id)
104 .map(LimitedVec)
105 }
106 }
107
108 fn visit_array<'scale, 'resolver>(
109 self,
110 value: &mut Array<'scale, 'resolver, Resolver>,
111 type_id: TypeIdFor<Self>,
112 ) -> Result<Self::Value<'scale, 'resolver>, Self::Error> {
113 if value.remaining() > N {
114 Err(scale_decode::Error::new(ErrorKind::WrongLength {
115 actual_len: value.remaining(),
116 expected_len: N,
117 }))
118 } else {
119 Vec::into_visitor()
120 .visit_array(value, type_id)
121 .map(LimitedVec)
122 }
123 }
124
125 fn visit_composite<'scale, 'resolver>(
126 self,
127 value: &mut Composite<'scale, 'resolver, Resolver>,
128 _type_id: TypeIdFor<Self>,
129 ) -> Result<Self::Value<'scale, 'resolver>, Self::Error> {
130 if value.remaining() != 1 {
131 return self.visit_unexpected(Unexpected::Composite);
132 }
133
134 value.decode_item(self).unwrap()
135 }
136
137 fn visit_tuple<'scale, 'resolver>(
138 self,
139 value: &mut Tuple<'scale, 'resolver, Resolver>,
140 _type_id: TypeIdFor<Self>,
141 ) -> Result<Self::Value<'scale, 'resolver>, Self::Error> {
142 if value.remaining() != 1 {
143 return self.visit_unexpected(Unexpected::Tuple);
144 }
145 value.decode_item(self).unwrap()
146 }
147}
148
149impl<T: IntoVisitor, const N: usize> IntoVisitor for LimitedVec<T, N> {
150 type AnyVisitor<R: TypeResolver> = LimitedVisitor<LimitedVec<T, N>, R>;
151
152 fn into_visitor<R: TypeResolver>() -> Self::AnyVisitor<R> {
153 LimitedVisitor::DEFAULT
154 }
155}
156
157impl<T: Clone, const N: usize> TryFrom<&[T]> for LimitedVec<T, N> {
158 type Error = LimitedVecError;
159
160 fn try_from(slice: &[T]) -> Result<Self, Self::Error> {
161 Self::validate_len(slice.len()).map(|_| Self(slice.to_vec()))
162 }
163}
164
165impl<T, const N: usize> TryFrom<Vec<T>> for LimitedVec<T, N> {
166 type Error = LimitedVecError;
167 fn try_from(vec: Vec<T>) -> Result<Self, Self::Error> {
168 Self::validate_len(vec.len()).map(|_| Self(vec))
169 }
170}
171
172impl<T, const N: usize> LimitedVec<T, N> {
173 pub const MAX_LEN: usize = N;
175
176 const fn validate_len(len: usize) -> Result<(), LimitedVecError> {
181 if len <= N {
182 Ok(())
183 } else {
184 Err(LimitedVecError)
185 }
186 }
187
188 pub const fn new() -> Self {
190 Self(vec![])
191 }
192
193 pub fn repeat(value: T) -> Self
196 where
197 T: Clone,
198 {
199 Self(vec![value; N])
200 }
201
202 pub fn try_repeat(value: T, len: usize) -> Result<Self, LimitedVecError>
205 where
206 T: Clone,
207 {
208 Self::validate_len(len).map(|_| Self(vec![value; len]))
209 }
210
211 pub fn extend_with(&mut self, value: T)
214 where
215 T: Clone,
216 {
217 self.0.resize(N, value)
218 }
219
220 pub fn try_push(&mut self, value: T) -> Result<(), LimitedVecError> {
222 Self::validate_len(self.len() + 1)?;
223
224 self.0.push(value);
225 Ok(())
226 }
227
228 pub fn try_extend_from_slice(&mut self, values: &[T]) -> Result<(), LimitedVecError>
230 where
231 T: Clone,
232 {
233 let new_len = self
234 .len()
235 .checked_add(values.len())
236 .ok_or(LimitedVecError)?;
237 Self::validate_len(new_len)?;
238
239 self.0.extend_from_slice(values);
240 Ok(())
241 }
242
243 pub fn as_slice(&self) -> &[T] {
245 self
246 }
247
248 pub fn to_vec(&self) -> Vec<T>
250 where
251 T: Clone,
252 {
253 self.0.clone()
254 }
255
256 pub fn into_vec(self) -> Vec<T> {
258 self.0
259 }
260}
261
262impl<T, const N: usize> fmt::Display for LimitedVec<T, N>
263where
264 [T]: AsRef<[u8]>,
265{
266 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
267 let bytes = ByteSliceFormatter::Dynamic(self.0.as_slice().as_ref());
268
269 let fmt_bytes = |f: &mut Formatter, bytes| {
279 if f.alternate() {
280 write!(f, "LimitedVec({bytes})")
281 } else {
282 write!(f, "{bytes}")
283 }
284 };
285
286 if let Some(precision) = f.precision() {
287 fmt_bytes(f, format_args!("{bytes:.precision$}"))
288 } else if f.sign_plus() {
289 fmt_bytes(f, format_args!("{bytes}"))
290 } else {
291 fmt_bytes(f, format_args!("{bytes:.8}"))
292 }
293 }
294}
295
296impl<T, const N: usize> fmt::Debug for LimitedVec<T, N>
297where
298 [T]: AsRef<[u8]>,
299{
300 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
301 fmt::Display::fmt(self, f)
302 }
303}
304
305#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, Display, Error)]
307#[display("{}", Self::MESSAGE)]
308pub struct LimitedVecError;
309
310impl LimitedVecError {
311 pub const MESSAGE: &str = "vector length limit is exceeded";
313
314 pub const fn as_str(&self) -> &'static str {
316 Self::MESSAGE
317 }
318}
319
320#[cfg(test)]
321mod test {
322 use super::LimitedVec;
323 use alloc::{string::String, vec, vec::Vec};
324 use core::convert::TryFrom;
325 use parity_scale_codec::{Decode, Encode};
326
327 const N: usize = 1000;
328 type TestBuffer = LimitedVec<u8, N>;
329 const M: usize = 64;
330 type SmallTestBuffer = LimitedVec<u8, M>;
331
332 #[test]
333 fn test_try_from() {
334 let v1 = vec![1; N];
335 let v2 = vec![1; N + 1];
336 let v3 = vec![1; N - 1];
337
338 let x = TestBuffer::try_from(v1).unwrap();
339 let _ = TestBuffer::try_from(v2).expect_err("Must be err because of size overflow");
340 let z = TestBuffer::try_from(v3).unwrap();
341
342 assert_eq!(x.len(), N);
343 assert_eq!(z.len(), N - 1);
344 assert_eq!(x[N / 2], 1);
345 assert_eq!(z[N / 2], 1);
346 }
347
348 #[test]
349 fn test_repeat() {
350 let x = LimitedVec::<u32, N>::repeat(0);
351 assert_eq!(x.len(), N);
352
353 let y = LimitedVec::<i32, 3>::repeat(-4);
354 assert_eq!(y.as_slice(), &[-4, -4, -4]);
355 }
356
357 #[test]
358 fn test_try_repeat() {
359 let x = LimitedVec::<String, N>::try_repeat(String::new(), N).unwrap();
360 assert!(
361 LimitedVec::<u64, N>::try_repeat(0, N + 1).is_err(),
362 "Must be error because of size overflow"
363 );
364 let y = LimitedVec::<char, 7>::try_repeat('@', 5).unwrap();
365 let z = LimitedVec::<Vec<u8>, N>::try_repeat(vec![], 0).unwrap();
366
367 assert_eq!(x.len(), N);
368 assert_eq!(z.len(), 0);
369 assert_eq!(x[N / 2], "");
370 assert_eq!(y.as_slice(), &['@', '@', '@', '@', '@']);
371 }
372
373 #[test]
374 fn test_full() {
375 let mut x = TestBuffer::try_from(vec![1; N]).unwrap();
376 let mut y = TestBuffer::try_from(vec![2; N / 2]).unwrap();
377 let mut z = TestBuffer::try_from(vec![3; 0]).unwrap();
378
379 x.try_extend_from_slice(&[1, 2, 3]).unwrap_err();
380 y.try_extend_from_slice(&[1, 2, 3]).unwrap();
381 z.try_extend_from_slice(&[1, 2, 3]).unwrap();
382
383 x.try_push(42).unwrap_err();
384 y.try_push(42).unwrap();
385 z.try_push(42).unwrap();
386
387 x.try_extend_from_slice(&[1, 2, 3]).unwrap_err();
388 y.try_extend_from_slice(&[1, 2, 3]).unwrap();
389 z.try_extend_from_slice(&[1, 2, 3]).unwrap();
390
391 z[0] = 0;
392
393 assert_eq!(&z.into_vec(), &[0, 2, 3, 42, 1, 2, 3]);
394 assert_eq!(TestBuffer::MAX_LEN, N);
395 }
396
397 #[test]
398 fn formatting_test() {
399 use alloc::format;
400
401 let buffer = SmallTestBuffer::try_from(b"abcdefghijklmnopqrstuvwxyz012345".to_vec())
402 .expect("String is 64 bytes");
403
404 assert_eq!(
406 format!("{buffer:+?}"),
407 "0x6162636465666768696a6b6c6d6e6f707172737475767778797a303132333435"
408 );
409 assert_eq!(
411 format!("{buffer:?}"),
412 "0x6162636465666768..797a303132333435"
413 );
414 assert_eq!(format!("{buffer:.0?}"), "0x..");
416 assert_eq!(format!("{buffer:.1?}"), "0x61..35");
418 assert_eq!(format!("{buffer:.2?}"), "0x6162..3435");
420 assert_eq!(format!("{buffer:.4?}"), "0x61626364..32333435");
422 assert_eq!(
424 format!("{buffer:.15?}"),
425 "0x6162636465666768696a6b6c6d6e6f..72737475767778797a303132333435"
426 );
427 assert_eq!(
429 format!("{buffer:.30?}"),
430 "0x6162636465666768696a6b6c6d6e6f707172737475767778797a303132333435"
431 );
432 assert_eq!(
434 format!("{buffer:#}"),
435 "LimitedVec(0x6162636465666768..797a303132333435)"
436 );
437 assert_eq!(
439 format!("{buffer:+#}"),
440 "LimitedVec(0x6162636465666768696a6b6c6d6e6f707172737475767778797a303132333435)"
441 );
442 assert_eq!(format!("{buffer:#.2}"), "LimitedVec(0x6162..3435)");
444 }
445
446 #[test]
447 fn test_decode() {
448 let normal_vec = vec![1, 2, 3, 4, 5];
450 let encoded_vec = normal_vec.encode();
451 let limited_vec = LimitedVec::<i32, 10>::decode(&mut &encoded_vec[..]).unwrap();
452
453 assert_eq!(normal_vec, limited_vec.into_vec());
454 }
455
456 #[test]
457 fn test_too_large_decode_fails() {
458 let bad_vec = vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11];
459 let encoded_vec = bad_vec.encode();
460
461 LimitedVec::<i32, 10>::decode(&mut &encoded_vec[..])
462 .err()
463 .expect("The vector must be too large");
464 }
465}