mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-04-27 10:27:59 +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:
@@ -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