Skip to main content

gear_core/limited/
vec.rs

1// Copyright (C) Gear Technologies Inc.
2// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0
3
4//! This module provides type for vector with statically limited length.
5
6use 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/// Vector with limited length.
29#[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    /// Maximum length of the vector.
174    pub const MAX_LEN: usize = N;
175
176    /// Validates given length.
177    ///
178    /// Returns `Ok(())` if the vector can store such number
179    /// of elements and `Err(LimitedVecError)` otherwise.
180    const fn validate_len(len: usize) -> Result<(), LimitedVecError> {
181        if len <= N {
182            Ok(())
183        } else {
184            Err(LimitedVecError)
185        }
186    }
187
188    /// Constructs a new, empty `LimitedVec<T>`.
189    pub const fn new() -> Self {
190        Self(vec![])
191    }
192
193    /// Creates a new limited vector with elements
194    /// initialized with [`Default::default`].
195    pub fn repeat(value: T) -> Self
196    where
197        T: Clone,
198    {
199        Self(vec![value; N])
200    }
201
202    /// Creates a new limited vector with given
203    /// length by repeatedly cloning a value.
204    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    /// Extends the vector to its limit by
212    /// repeatedly adding a value.
213    pub fn extend_with(&mut self, value: T)
214    where
215        T: Clone,
216    {
217        self.0.resize(N, value)
218    }
219
220    /// Appends a value to the end of the vector.
221    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    /// Appends values from slice to the end of vector.
229    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    /// Returns a slice reference to the vector contents.
244    pub fn as_slice(&self) -> &[T] {
245        self
246    }
247
248    /// Clones the limited vector into `Vec<T>`.
249    pub fn to_vec(&self) -> Vec<T>
250    where
251        T: Clone,
252    {
253        self.0.clone()
254    }
255
256    /// Converts the limited vector into its inner `Vec<T>`.
257    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        // FIXME: this hacky trick with a function is required
270        //        because of inability to put `format_args!(...)`
271        //        into a variable. It can be replaced with something
272        //        more straightforward when `formatting_options`
273        //        is stabilized.
274        //
275        // See:
276        // - https://doc.rust-lang.org/stable/std/macro.format_args.html#lifetime-limitation
277        // - https://doc.rust-lang.org/stable/std/fmt/struct.Formatter.html#method.with_options
278        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/// Error type for limited vector overflowing.
306#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, Display, Error)]
307#[display("{}", Self::MESSAGE)]
308pub struct LimitedVecError;
309
310impl LimitedVecError {
311    /// Static error message.
312    pub const MESSAGE: &str = "vector length limit is exceeded";
313
314    /// Converts the error into a static error message.
315    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        // `Debug`/`Display`.
405        assert_eq!(
406            format!("{buffer:+?}"),
407            "0x6162636465666768696a6b6c6d6e6f707172737475767778797a303132333435"
408        );
409        // `Debug`/`Display` with default precision.
410        assert_eq!(
411            format!("{buffer:?}"),
412            "0x6162636465666768..797a303132333435"
413        );
414        // `Debug`/`Display` with precision 0.
415        assert_eq!(format!("{buffer:.0?}"), "0x..");
416        // `Debug`/`Display` with precision 1.
417        assert_eq!(format!("{buffer:.1?}"), "0x61..35");
418        // `Debug`/`Display` with precision 2.
419        assert_eq!(format!("{buffer:.2?}"), "0x6162..3435");
420        // `Debug`/`Display` with precision 4.
421        assert_eq!(format!("{buffer:.4?}"), "0x61626364..32333435");
422        // `Debug`/`Display` with precision 15.
423        assert_eq!(
424            format!("{buffer:.15?}"),
425            "0x6162636465666768696a6b6c6d6e6f..72737475767778797a303132333435"
426        );
427        // `Debug`/`Display` with precision 30.
428        assert_eq!(
429            format!("{buffer:.30?}"),
430            "0x6162636465666768696a6b6c6d6e6f707172737475767778797a303132333435"
431        );
432        // Alternate formatter with default precision.
433        assert_eq!(
434            format!("{buffer:#}"),
435            "LimitedVec(0x6162636465666768..797a303132333435)"
436        );
437        // Alternate formatter with max precision.
438        assert_eq!(
439            format!("{buffer:+#}"),
440            "LimitedVec(0x6162636465666768696a6b6c6d6e6f707172737475767778797a303132333435)"
441        );
442        // Alternate formatter with precision 2.
443        assert_eq!(format!("{buffer:#.2}"), "LimitedVec(0x6162..3435)");
444    }
445
446    #[test]
447    fn test_decode() {
448        // Limited vector is encoded just like a normal vector
449        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}