diff --git a/primitives/runtime/src/bounded/bounded_btree_map.rs b/primitives/runtime/src/bounded/bounded_btree_map.rs index f4fd4275beb2a..b9abf77f175c6 100644 --- a/primitives/runtime/src/bounded/bounded_btree_map.rs +++ b/primitives/runtime/src/bounded/bounded_btree_map.rs @@ -66,6 +66,11 @@ where K: Ord, S: Get, { + /// Create `Self` from `t` without any checks. + fn unchecked_from(t: BTreeMap) -> Self { + Self(t, Default::default()) + } + /// Exactly the same semantics as `BTreeMap::retain`. /// /// The is a safe `&mut self` borrow because `retain` can only ever decrease the length of the @@ -344,8 +349,7 @@ where if self.len() > Bound::get() as usize { Err("iterator length too big") } else { - Ok(BoundedBTreeMap::::try_from(self.collect::>()) - .expect("length checked above; qed")) + Ok(BoundedBTreeMap::::unchecked_from(self.collect::>())) } } } diff --git a/primitives/runtime/src/bounded/bounded_btree_set.rs b/primitives/runtime/src/bounded/bounded_btree_set.rs index 40b95165da1bd..0f8cc769e47e3 100644 --- a/primitives/runtime/src/bounded/bounded_btree_set.rs +++ b/primitives/runtime/src/bounded/bounded_btree_set.rs @@ -65,6 +65,11 @@ where T: Ord, S: Get, { + /// Create `Self` from `t` without any checks. + fn unchecked_from(t: BTreeSet) -> Self { + Self(t, Default::default()) + } + /// Create a new `BoundedBTreeSet`. /// /// Does not allocate. @@ -309,8 +314,7 @@ where if self.len() > Bound::get() as usize { Err("iterator length too big") } else { - Ok(BoundedBTreeSet::::try_from(self.collect::>()) - .expect("length is checked above; qed")) + Ok(BoundedBTreeSet::::unchecked_from(self.collect::>())) } } } diff --git a/primitives/runtime/src/bounded/bounded_vec.rs b/primitives/runtime/src/bounded/bounded_vec.rs index 4493d9f8b0198..9231c83fc7675 100644 --- a/primitives/runtime/src/bounded/bounded_vec.rs +++ b/primitives/runtime/src/bounded/bounded_vec.rs @@ -43,7 +43,7 @@ use sp_std::{marker::PhantomData, prelude::*}; #[derive(Encode, scale_info::TypeInfo)] #[scale_info(skip_type_params(S))] pub struct BoundedVec( - Vec, + pub(super) Vec, #[cfg_attr(feature = "std", serde(skip_serializing))] PhantomData, ); @@ -106,7 +106,7 @@ where /// Similar to a `BoundedVec`, but not owned and cannot be decoded. #[derive(Encode, scale_info::TypeInfo)] #[scale_info(skip_type_params(S))] -pub struct BoundedSlice<'a, T, S>(&'a [T], PhantomData); +pub struct BoundedSlice<'a, T, S>(pub(super) &'a [T], PhantomData); // `BoundedSlice`s encode to something which will always decode into a `BoundedVec`, // `WeakBoundedVec`, or a `Vec`. @@ -117,13 +117,81 @@ impl<'a, T: Encode + Decode, S: Get> EncodeLike> } impl<'a, T: Encode + Decode, S: Get> EncodeLike> for BoundedSlice<'a, T, S> {} -impl> PartialOrd for BoundedVec { - fn partial_cmp(&self, other: &Self) -> Option { - self.0.partial_cmp(&other.0) +impl<'a, T, BoundSelf, BoundRhs> PartialEq> + for BoundedSlice<'a, T, BoundSelf> +where + T: PartialEq, + BoundSelf: Get, + BoundRhs: Get, +{ + fn eq(&self, other: &BoundedSlice<'a, T, BoundRhs>) -> bool { + self.0 == other.0 } } -impl> Ord for BoundedVec { +impl<'a, T, BoundSelf, BoundRhs> PartialEq> + for BoundedSlice<'a, T, BoundSelf> +where + T: PartialEq, + BoundSelf: Get, + BoundRhs: Get, +{ + fn eq(&self, other: &BoundedVec) -> bool { + self.0 == other.0 + } +} + +impl<'a, T, BoundSelf, BoundRhs> PartialEq> + for BoundedSlice<'a, T, BoundSelf> +where + T: PartialEq, + BoundSelf: Get, + BoundRhs: Get, +{ + fn eq(&self, other: &WeakBoundedVec) -> bool { + self.0 == other.0 + } +} + +impl<'a, T, S: Get> Eq for BoundedSlice<'a, T, S> where T: Eq {} + +impl<'a, T, BoundSelf, BoundRhs> PartialOrd> + for BoundedSlice<'a, T, BoundSelf> +where + T: PartialOrd, + BoundSelf: Get, + BoundRhs: Get, +{ + fn partial_cmp(&self, other: &BoundedSlice<'a, T, BoundRhs>) -> Option { + self.0.partial_cmp(other.0) + } +} + +impl<'a, T, BoundSelf, BoundRhs> PartialOrd> + for BoundedSlice<'a, T, BoundSelf> +where + T: PartialOrd, + BoundSelf: Get, + BoundRhs: Get, +{ + fn partial_cmp(&self, other: &BoundedVec) -> Option { + self.0.partial_cmp(&*other.0) + } +} + +impl<'a, T, BoundSelf, BoundRhs> PartialOrd> + for BoundedSlice<'a, T, BoundSelf> +where + T: PartialOrd, + BoundSelf: Get, + BoundRhs: Get, +{ + fn partial_cmp(&self, other: &WeakBoundedVec) -> Option { + self.0.partial_cmp(&*other.0) + } +} + +impl<'a, T: Ord, Bound: Get> Ord for BoundedSlice<'a, T, Bound> { fn cmp(&self, other: &Self) -> sp_std::cmp::Ordering { self.0.cmp(&other.0) } @@ -641,7 +709,30 @@ where BoundRhs: Get, { fn eq(&self, rhs: &BoundedVec) -> bool { - BoundSelf::get() == BoundRhs::get() && self.0 == rhs.0 + self.0 == rhs.0 + } +} + +impl PartialEq> for BoundedVec +where + T: PartialEq, + BoundSelf: Get, + BoundRhs: Get, +{ + fn eq(&self, rhs: &WeakBoundedVec) -> bool { + self.0 == rhs.0 + } +} + +impl<'a, T, BoundSelf, BoundRhs> PartialEq> + for BoundedVec +where + T: PartialEq, + BoundSelf: Get, + BoundRhs: Get, +{ + fn eq(&self, rhs: &BoundedSlice<'a, T, BoundRhs>) -> bool { + self.0 == rhs.0 } } @@ -653,6 +744,46 @@ impl> PartialEq> for BoundedVec { impl> Eq for BoundedVec where T: Eq {} +impl PartialOrd> for BoundedVec +where + T: PartialOrd, + BoundSelf: Get, + BoundRhs: Get, +{ + fn partial_cmp(&self, other: &BoundedVec) -> Option { + self.0.partial_cmp(&other.0) + } +} + +impl PartialOrd> for BoundedVec +where + T: PartialOrd, + BoundSelf: Get, + BoundRhs: Get, +{ + fn partial_cmp(&self, other: &WeakBoundedVec) -> Option { + self.0.partial_cmp(&other.0) + } +} + +impl<'a, T, BoundSelf, BoundRhs> PartialOrd> + for BoundedVec +where + T: PartialOrd, + BoundSelf: Get, + BoundRhs: Get, +{ + fn partial_cmp(&self, other: &BoundedSlice<'a, T, BoundRhs>) -> Option { + (&*self.0).partial_cmp(other.0) + } +} + +impl> Ord for BoundedVec { + fn cmp(&self, other: &Self) -> sp_std::cmp::Ordering { + self.0.cmp(&other.0) + } +} + impl MaxEncodedLen for BoundedVec where T: MaxEncodedLen, diff --git a/primitives/runtime/src/bounded/weak_bounded_vec.rs b/primitives/runtime/src/bounded/weak_bounded_vec.rs index 9b88ad27e4287..82bae4118f13e 100644 --- a/primitives/runtime/src/bounded/weak_bounded_vec.rs +++ b/primitives/runtime/src/bounded/weak_bounded_vec.rs @@ -18,6 +18,7 @@ //! Traits, types and structs to support putting a bounded vector into storage, as a raw value, map //! or a double map. +use super::{BoundedSlice, BoundedVec}; use crate::traits::Get; use codec::{Decode, Encode, MaxEncodedLen}; use core::{ @@ -35,7 +36,7 @@ use sp_std::{marker::PhantomData, prelude::*}; /// is accepted, and some method allow to bypass the restriction with warnings. #[derive(Encode, scale_info::TypeInfo)] #[scale_info(skip_type_params(S))] -pub struct WeakBoundedVec(Vec, PhantomData); +pub struct WeakBoundedVec(pub(super) Vec, PhantomData); impl> Decode for WeakBoundedVec { fn decode(input: &mut I) -> Result { @@ -283,14 +284,36 @@ impl codec::DecodeLength for WeakBoundedVec { } } -// NOTE: we could also implement this as: -// impl, S2: Get> PartialEq> for WeakBoundedVec to allow comparison of bounded vectors with different bounds. -impl PartialEq for WeakBoundedVec +impl PartialEq> for WeakBoundedVec where T: PartialEq, + BoundSelf: Get, + BoundRhs: Get, { - fn eq(&self, rhs: &Self) -> bool { + fn eq(&self, rhs: &WeakBoundedVec) -> bool { + self.0 == rhs.0 + } +} + +impl PartialEq> for WeakBoundedVec +where + T: PartialEq, + BoundSelf: Get, + BoundRhs: Get, +{ + fn eq(&self, rhs: &BoundedVec) -> bool { + self.0 == rhs.0 + } +} + +impl<'a, T, BoundSelf, BoundRhs> PartialEq> + for WeakBoundedVec +where + T: PartialEq, + BoundSelf: Get, + BoundRhs: Get, +{ + fn eq(&self, rhs: &BoundedSlice<'a, T, BoundRhs>) -> bool { self.0 == rhs.0 } } @@ -301,7 +324,48 @@ impl> PartialEq> for WeakBoundedVec { } } -impl Eq for WeakBoundedVec where T: Eq {} +impl> Eq for WeakBoundedVec where T: Eq {} + +impl PartialOrd> + for WeakBoundedVec +where + T: PartialOrd, + BoundSelf: Get, + BoundRhs: Get, +{ + fn partial_cmp(&self, other: &WeakBoundedVec) -> Option { + self.0.partial_cmp(&other.0) + } +} + +impl PartialOrd> for WeakBoundedVec +where + T: PartialOrd, + BoundSelf: Get, + BoundRhs: Get, +{ + fn partial_cmp(&self, other: &BoundedVec) -> Option { + self.0.partial_cmp(&other.0) + } +} + +impl<'a, T, BoundSelf, BoundRhs> PartialOrd> + for WeakBoundedVec +where + T: PartialOrd, + BoundSelf: Get, + BoundRhs: Get, +{ + fn partial_cmp(&self, other: &BoundedSlice<'a, T, BoundRhs>) -> Option { + (&*self.0).partial_cmp(other.0) + } +} + +impl> Ord for WeakBoundedVec { + fn cmp(&self, other: &Self) -> sp_std::cmp::Ordering { + self.0.cmp(&other.0) + } +} impl MaxEncodedLen for WeakBoundedVec where