From 5fb7658ae9fc9382d8eed71ba58e52227c0976c7 Mon Sep 17 00:00:00 2001 From: Shawn Tabrizi <shawntabrizi@gmail.com> Date: Tue, 4 May 2021 05:17:52 -0400 Subject: [PATCH] Improve `BoundedVec` API (#8707) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * improve bounded vec api * Update frame/support/src/storage/bounded_vec.rs Co-authored-by: Guillaume Thiolliere <gui.thiolliere@gmail.com> * Update frame/support/src/storage/bounded_vec.rs * Update frame/support/src/storage/bounded_vec.rs Co-authored-by: Guillaume Thiolliere <gui.thiolliere@gmail.com> Co-authored-by: Bastian Köcher <bkchr@users.noreply.github.com> --- .../frame/support/src/storage/bounded_vec.rs | 48 +++++++++++++++++-- 1 file changed, 44 insertions(+), 4 deletions(-) diff --git a/substrate/frame/support/src/storage/bounded_vec.rs b/substrate/frame/support/src/storage/bounded_vec.rs index 9fcfe403529..5b253f76333 100644 --- a/substrate/frame/support/src/storage/bounded_vec.rs +++ b/substrate/frame/support/src/storage/bounded_vec.rs @@ -21,6 +21,7 @@ use sp_std::prelude::*; use sp_std::{convert::TryFrom, marker::PhantomData}; use codec::{FullCodec, Encode, EncodeLike, Decode}; +use core::{ops::{Index, IndexMut}, slice::SliceIndex}; use crate::{ traits::Get, storage::{generator, StorageDecodeLength, StorageValue, StorageMap, StorageDoubleMap}, @@ -179,6 +180,18 @@ impl<T: BoundedVecValue, S: Get<u32>> AsRef<Vec<T>> for BoundedVec<T, S> { } } +impl<T: BoundedVecValue, S: Get<u32>> AsRef<[T]> for BoundedVec<T, S> { + fn as_ref(&self) -> &[T] { + &self.0 + } +} + +impl<T: BoundedVecValue, S: Get<u32>> AsMut<[T]> for BoundedVec<T, S> { + fn as_mut(&mut self) -> &mut [T] { + &mut self.0 + } +} + // will allow for immutable all operations of `Vec<T>` on `BoundedVec<T>`. impl<T: BoundedVecValue, S: Get<u32>> sp_std::ops::Deref for BoundedVec<T, S> { type Target = Vec<T>; @@ -189,10 +202,19 @@ impl<T: BoundedVecValue, S: Get<u32>> sp_std::ops::Deref for BoundedVec<T, S> { } // Allows for indexing similar to a normal `Vec`. Can panic if out of bound. -impl<T: BoundedVecValue, S: Get<u32>> sp_std::ops::Index<usize> for BoundedVec<T, S> { - type Output = T; - fn index(&self, index: usize) -> &Self::Output { - self.get(index).expect("index out of bound") +impl<T: BoundedVecValue, S: Get<u32>, I: SliceIndex<[T]>> Index<I> for BoundedVec<T, S> { + type Output = I::Output; + + #[inline] + fn index(&self, index: I) -> &Self::Output { + self.0.index(index) + } +} + +impl<T: BoundedVecValue, S: Get<u32>, I: SliceIndex<[T]>> IndexMut<I> for BoundedVec<T, S> { + #[inline] + fn index_mut(&mut self, index: I) -> &mut Self::Output { + self.0.index_mut(index) } } @@ -212,6 +234,12 @@ impl<T: BoundedVecValue, S: Get<u32>> codec::DecodeLength for BoundedVec<T, S> { } } +impl<T: BoundedVecValue + PartialEq, S: Get<u32>> PartialEq<Vec<T>> for BoundedVec<T, S> { + fn eq(&self, other: &Vec<T>) -> bool { + &self.0 == other + } +} + impl<T: BoundedVecValue, S: Get<u32>> StorageDecodeLength for BoundedVec<T, S> {} /// Storage value that is *maybe* capable of [`StorageAppend`](crate::storage::StorageAppend). @@ -467,4 +495,16 @@ pub mod test { assert_eq!(bounded.len(), 7); assert!(bounded.try_mutate(|v| v.push(8)).is_none()); } + + #[test] + fn slice_indexing_works() { + let bounded: BoundedVec<u32, Seven> = vec![1, 2, 3, 4, 5, 6].try_into().unwrap(); + assert_eq!(&bounded[0..=2], &[1, 2, 3]); + } + + #[test] + fn vec_eq_works() { + let bounded: BoundedVec<u32, Seven> = vec![1, 2, 3, 4, 5, 6].try_into().unwrap(); + assert_eq!(bounded, vec![1, 2, 3, 4, 5, 6]); + } } -- GitLab