mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-04-26 18:07:58 +00:00
Introduce DefensiveMin and DefensiveMax (#12554)
* traits for defensive min and defensive max * defensive min and strict min with tests * defensive max and strict max with tests * include docs * implement partial ord on defensive min and max * Update frame/support/src/traits/misc.rs Co-authored-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> * wrap lines * Fix traits Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> * Update frame/support/src/traits/misc.rs * Update frame/support/src/traits/misc.rs Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> Co-authored-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> Co-authored-by: parity-processbot <>
This commit is contained in:
@@ -56,11 +56,11 @@ mod misc;
|
||||
pub use misc::{
|
||||
defensive_prelude::{self, *},
|
||||
Backing, ConstBool, ConstI128, ConstI16, ConstI32, ConstI64, ConstI8, ConstU128, ConstU16,
|
||||
ConstU32, ConstU64, ConstU8, DefensiveSaturating, DefensiveTruncateFrom,
|
||||
EnsureInherentsAreFirst, EqualPrivilegeOnly, EstimateCallFee, ExecuteBlock, ExtrinsicCall, Get,
|
||||
GetBacking, GetDefault, HandleLifetime, IsSubType, IsType, Len, OffchainWorker,
|
||||
OnKilledAccount, OnNewAccount, PrivilegeCmp, SameOrOther, Time, TryCollect, TryDrop, TypedGet,
|
||||
UnixTime, WrapperKeepOpaque, WrapperOpaque,
|
||||
ConstU32, ConstU64, ConstU8, DefensiveMax, DefensiveMin, DefensiveSaturating,
|
||||
DefensiveTruncateFrom, EnsureInherentsAreFirst, EqualPrivilegeOnly, EstimateCallFee,
|
||||
ExecuteBlock, ExtrinsicCall, Get, GetBacking, GetDefault, HandleLifetime, IsSubType, IsType,
|
||||
Len, OffchainWorker, OnKilledAccount, OnNewAccount, PrivilegeCmp, SameOrOther, Time,
|
||||
TryCollect, TryDrop, TypedGet, UnixTime, WrapperKeepOpaque, WrapperOpaque,
|
||||
};
|
||||
#[allow(deprecated)]
|
||||
pub use misc::{PreimageProvider, PreimageRecipient};
|
||||
|
||||
@@ -407,6 +407,134 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
/// Defensively calculates the minimum of two values.
|
||||
///
|
||||
/// Can be used in contexts where we assume the receiver value to be (strictly) smaller.
|
||||
pub trait DefensiveMin<T> {
|
||||
/// Returns the minimum and defensively checks that `self` is not larger than `other`.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```
|
||||
/// use frame_support::traits::DefensiveMin;
|
||||
/// // min(3, 4) is 3.
|
||||
/// assert_eq!(3, 3_u32.defensive_min(4_u32));
|
||||
/// // min(4, 4) is 4.
|
||||
/// assert_eq!(4, 4_u32.defensive_min(4_u32));
|
||||
/// ```
|
||||
///
|
||||
/// ```should_panic
|
||||
/// use frame_support::traits::DefensiveMin;
|
||||
/// // min(4, 3) panics.
|
||||
/// 4_u32.defensive_min(3_u32);
|
||||
/// ```
|
||||
fn defensive_min(self, other: T) -> Self;
|
||||
|
||||
/// Returns the minimum and defensively checks that `self` is smaller than `other`.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```
|
||||
/// use frame_support::traits::DefensiveMin;
|
||||
/// // min(3, 4) is 3.
|
||||
/// assert_eq!(3, 3_u32.defensive_strict_min(4_u32));
|
||||
/// ```
|
||||
///
|
||||
/// ```should_panic
|
||||
/// use frame_support::traits::DefensiveMin;
|
||||
/// // min(4, 4) panics.
|
||||
/// 4_u32.defensive_strict_min(4_u32);
|
||||
/// ```
|
||||
fn defensive_strict_min(self, other: T) -> Self;
|
||||
}
|
||||
|
||||
impl<T> DefensiveMin<T> for T
|
||||
where
|
||||
T: sp_std::cmp::PartialOrd<T>,
|
||||
{
|
||||
fn defensive_min(self, other: T) -> Self {
|
||||
if self <= other {
|
||||
self
|
||||
} else {
|
||||
defensive!("DefensiveMin");
|
||||
other
|
||||
}
|
||||
}
|
||||
|
||||
fn defensive_strict_min(self, other: T) -> Self {
|
||||
if self < other {
|
||||
self
|
||||
} else {
|
||||
defensive!("DefensiveMin strict");
|
||||
other
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Defensively calculates the maximum of two values.
|
||||
///
|
||||
/// Can be used in contexts where we assume the receiver value to be (strictly) larger.
|
||||
pub trait DefensiveMax<T> {
|
||||
/// Returns the maximum and defensively asserts that `other` is not larger than `self`.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```
|
||||
/// use frame_support::traits::DefensiveMax;
|
||||
/// // max(4, 3) is 4.
|
||||
/// assert_eq!(4, 4_u32.defensive_max(3_u32));
|
||||
/// // max(4, 4) is 4.
|
||||
/// assert_eq!(4, 4_u32.defensive_max(4_u32));
|
||||
/// ```
|
||||
///
|
||||
/// ```should_panic
|
||||
/// use frame_support::traits::DefensiveMax;
|
||||
/// // max(4, 5) panics.
|
||||
/// 4_u32.defensive_max(5_u32);
|
||||
/// ```
|
||||
fn defensive_max(self, other: T) -> Self;
|
||||
|
||||
/// Returns the maximum and defensively asserts that `other` is smaller than `self`.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```
|
||||
/// use frame_support::traits::DefensiveMax;
|
||||
/// // y(4, 3) is 4.
|
||||
/// assert_eq!(4, 4_u32.defensive_strict_max(3_u32));
|
||||
/// ```
|
||||
///
|
||||
/// ```should_panic
|
||||
/// use frame_support::traits::DefensiveMax;
|
||||
/// // max(4, 4) panics.
|
||||
/// 4_u32.defensive_strict_max(4_u32);
|
||||
/// ```
|
||||
fn defensive_strict_max(self, other: T) -> Self;
|
||||
}
|
||||
|
||||
impl<T> DefensiveMax<T> for T
|
||||
where
|
||||
T: sp_std::cmp::PartialOrd<T>,
|
||||
{
|
||||
fn defensive_max(self, other: T) -> Self {
|
||||
if self >= other {
|
||||
self
|
||||
} else {
|
||||
defensive!("DefensiveMax");
|
||||
other
|
||||
}
|
||||
}
|
||||
|
||||
fn defensive_strict_max(self, other: T) -> Self {
|
||||
if self > other {
|
||||
self
|
||||
} else {
|
||||
defensive!("DefensiveMax strict");
|
||||
other
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Anything that can have a `::len()` method.
|
||||
pub trait Len {
|
||||
/// Return the length of data type.
|
||||
@@ -1109,4 +1237,52 @@ mod test {
|
||||
let data = decoded.encode();
|
||||
WrapperOpaque::<u32>::decode(&mut &data[..]).unwrap();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn defensive_min_works() {
|
||||
assert_eq!(10, 10_u32.defensive_min(11_u32));
|
||||
assert_eq!(10, 10_u32.defensive_min(10_u32));
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_panic(expected = "Defensive failure has been triggered!: \"DefensiveMin\"")]
|
||||
fn defensive_min_panics() {
|
||||
10_u32.defensive_min(9_u32);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn defensive_strict_min_works() {
|
||||
assert_eq!(10, 10_u32.defensive_strict_min(11_u32));
|
||||
assert_eq!(9, 9_u32.defensive_strict_min(10_u32));
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_panic(expected = "Defensive failure has been triggered!: \"DefensiveMin strict\"")]
|
||||
fn defensive_strict_min_panics() {
|
||||
9_u32.defensive_strict_min(9_u32);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn defensive_max_works() {
|
||||
assert_eq!(11, 11_u32.defensive_max(10_u32));
|
||||
assert_eq!(10, 10_u32.defensive_max(10_u32));
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_panic(expected = "Defensive failure has been triggered!: \"DefensiveMax\"")]
|
||||
fn defensive_max_panics() {
|
||||
9_u32.defensive_max(10_u32);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn defensive_strict_max_works() {
|
||||
assert_eq!(11, 11_u32.defensive_strict_max(10_u32));
|
||||
assert_eq!(10, 10_u32.defensive_strict_max(9_u32));
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_panic(expected = "Defensive failure has been triggered!: \"DefensiveMax strict\"")]
|
||||
fn defensive_strict_max_panics() {
|
||||
9_u32.defensive_strict_max(9_u32);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user