Merge rust-bitcoin/rust-bitcoin#4461: Implementing Div<NonZeroU64|I64> for Amount, SignedAmount, FeeRate, and and Weight
fe577cd04e
Implement Div<NonZeroU64|I64> for Amount, SignedAmount, FeeRate, and Weight (frankomosh) Pull request description: The pr implements `Div<NonZeroU64>` and `Div<NonZeroI64>` for the following types in `units` crate: `Amount`, `SignedAmount`, `FeeRate`, `Weight` For handling owned/borrowed variants, each impl is wrapped in the existing `impl_op_for_references!` macro, which generates: `T / NonZero*` , `&T / NonZero*`, `T / &NonZero*`, `&T / &NonZero*` close: #4442 ACKs for top commit: Kixunil: ACKfe577cd04e
apoelstra: ACK fe577cd04e64488371aa62b872e2b88050d4948f; successfully ran local tests tcharding: ACKfe577cd04e
Tree-SHA512: b9b4a9f46d2fcf559d0a7f62ec397b6c2b174dd8ca9d80b37c0c393894ab4bc32019d64e2afcad1f780442b16aa3d15240ce607fc14b5e17b112243f7556b5b4
This commit is contained in:
commit
fc373f3a37
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
//! Provides a monodic type returned by mathematical operations (`core::ops`).
|
//! Provides a monodic type returned by mathematical operations (`core::ops`).
|
||||||
|
|
||||||
|
use core::num::{NonZeroI64, NonZeroU64};
|
||||||
use core::ops;
|
use core::ops;
|
||||||
|
|
||||||
use NumOpResult as R;
|
use NumOpResult as R;
|
||||||
|
@ -90,7 +91,11 @@ crate::internal_macros::impl_op_for_references! {
|
||||||
self.to_sat().checked_div(rhs.to_sat()).valid_or_error(MathOp::Div)
|
self.to_sat().checked_div(rhs.to_sat()).valid_or_error(MathOp::Div)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
impl ops::Div<NonZeroU64> for Amount {
|
||||||
|
type Output = Amount;
|
||||||
|
|
||||||
|
fn div(self, rhs: NonZeroU64) -> Self::Output { Self::from_sat(self.to_sat() / rhs.get()).expect("construction after division cannot fail") }
|
||||||
|
}
|
||||||
impl ops::Rem<u64> for Amount {
|
impl ops::Rem<u64> for Amount {
|
||||||
type Output = NumOpResult<Amount>;
|
type Output = NumOpResult<Amount>;
|
||||||
|
|
||||||
|
@ -167,7 +172,11 @@ crate::internal_macros::impl_op_for_references! {
|
||||||
self.to_sat().checked_div(rhs.to_sat()).valid_or_error(MathOp::Div)
|
self.to_sat().checked_div(rhs.to_sat()).valid_or_error(MathOp::Div)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
impl ops::Div<NonZeroI64> for SignedAmount {
|
||||||
|
type Output = SignedAmount;
|
||||||
|
|
||||||
|
fn div(self, rhs: NonZeroI64) -> Self::Output { Self::from_sat(self.to_sat() / rhs.get()).expect("construction after division cannot fail") }
|
||||||
|
}
|
||||||
impl ops::Rem<i64> for SignedAmount {
|
impl ops::Rem<i64> for SignedAmount {
|
||||||
type Output = NumOpResult<SignedAmount>;
|
type Output = NumOpResult<SignedAmount>;
|
||||||
|
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
use alloc::format;
|
use alloc::format;
|
||||||
#[cfg(feature = "alloc")]
|
#[cfg(feature = "alloc")]
|
||||||
use alloc::string::{String, ToString};
|
use alloc::string::{String, ToString};
|
||||||
|
use core::num::{NonZeroI64, NonZeroU64};
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
use std::panic;
|
use std::panic;
|
||||||
|
|
||||||
|
@ -1530,3 +1531,26 @@ fn math_op_errors() {
|
||||||
panic!("Expected a division by zero error, but got a valid result");
|
panic!("Expected a division by zero error, but got a valid result");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
#[allow(clippy::op_ref)]
|
||||||
|
fn amount_div_nonzero() {
|
||||||
|
let amount = Amount::from_sat(100).unwrap();
|
||||||
|
let divisor = NonZeroU64::new(4).unwrap();
|
||||||
|
let result = amount / divisor;
|
||||||
|
assert_eq!(result, Amount::from_sat(25).unwrap());
|
||||||
|
//checking also for &T/&U variant
|
||||||
|
assert_eq!(&amount / &divisor, Amount::from_sat(25).unwrap());
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
#[allow(clippy::op_ref)]
|
||||||
|
fn signed_amount_div_nonzero() {
|
||||||
|
let signed = SignedAmount::from_sat(-100).unwrap();
|
||||||
|
let divisor = NonZeroI64::new(4).unwrap();
|
||||||
|
let result = signed / divisor;
|
||||||
|
assert_eq!(result, SignedAmount::from_sat(-25).unwrap());
|
||||||
|
//checking also for &T/U, T/&Uvariant
|
||||||
|
assert_eq!(&signed / divisor, SignedAmount::from_sat(-25).unwrap());
|
||||||
|
assert_eq!(signed / &divisor, SignedAmount::from_sat(-25).unwrap());
|
||||||
|
}
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
#[cfg(feature = "serde")]
|
#[cfg(feature = "serde")]
|
||||||
pub mod serde;
|
pub mod serde;
|
||||||
|
|
||||||
|
use core::num::NonZeroU64;
|
||||||
use core::{fmt, ops};
|
use core::{fmt, ops};
|
||||||
|
|
||||||
#[cfg(feature = "arbitrary")]
|
#[cfg(feature = "arbitrary")]
|
||||||
|
@ -157,6 +158,12 @@ crate::internal_macros::impl_op_for_references! {
|
||||||
|
|
||||||
fn sub(self, rhs: FeeRate) -> Self::Output { FeeRate::from_sat_per_kwu(self.to_sat_per_kwu() - rhs.to_sat_per_kwu()) }
|
fn sub(self, rhs: FeeRate) -> Self::Output { FeeRate::from_sat_per_kwu(self.to_sat_per_kwu() - rhs.to_sat_per_kwu()) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl ops::Div<NonZeroU64> for FeeRate {
|
||||||
|
type Output = FeeRate;
|
||||||
|
|
||||||
|
fn div(self, rhs: NonZeroU64) -> Self::Output{ Self::from_sat_per_kwu(self.to_sat_per_kwu() / rhs.get()) }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
crate::internal_macros::impl_add_assign!(FeeRate);
|
crate::internal_macros::impl_add_assign!(FeeRate);
|
||||||
crate::internal_macros::impl_sub_assign!(FeeRate);
|
crate::internal_macros::impl_sub_assign!(FeeRate);
|
||||||
|
@ -198,6 +205,7 @@ impl<'a> Arbitrary<'a> for FeeRate {
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
use core::num::NonZeroU64;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn sanity_check() {
|
fn sanity_check() {
|
||||||
|
@ -205,6 +213,15 @@ mod tests {
|
||||||
assert_eq!(fee_rate, 100_u64);
|
assert_eq!(fee_rate, 100_u64);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
#[allow(clippy::op_ref)]
|
||||||
|
fn feerate_div_nonzero() {
|
||||||
|
let rate = FeeRate::from_sat_per_kwu(200);
|
||||||
|
let divisor = NonZeroU64::new(2).unwrap();
|
||||||
|
assert_eq!(rate / divisor, FeeRate::from_sat_per_kwu(100));
|
||||||
|
assert_eq!(&rate / &divisor, FeeRate::from_sat_per_kwu(100));
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
#[allow(clippy::op_ref)]
|
#[allow(clippy::op_ref)]
|
||||||
fn addition() {
|
fn addition() {
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
//! Implements `Weight` and associated features.
|
//! Implements `Weight` and associated features.
|
||||||
|
|
||||||
|
use core::num::NonZeroU64;
|
||||||
use core::{fmt, ops};
|
use core::{fmt, ops};
|
||||||
|
|
||||||
#[cfg(feature = "arbitrary")]
|
#[cfg(feature = "arbitrary")]
|
||||||
|
@ -221,6 +222,11 @@ crate::internal_macros::impl_op_for_references! {
|
||||||
|
|
||||||
fn rem(self, rhs: Weight) -> Self::Output { self.to_wu() % rhs.to_wu() }
|
fn rem(self, rhs: Weight) -> Self::Output { self.to_wu() % rhs.to_wu() }
|
||||||
}
|
}
|
||||||
|
impl ops::Div<NonZeroU64> for Weight {
|
||||||
|
type Output = Weight;
|
||||||
|
|
||||||
|
fn div(self, rhs: NonZeroU64) -> Self::Output{ Self::from_wu(self.to_wu() / rhs.get()) }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
crate::internal_macros::impl_add_assign!(Weight);
|
crate::internal_macros::impl_add_assign!(Weight);
|
||||||
crate::internal_macros::impl_sub_assign!(Weight);
|
crate::internal_macros::impl_sub_assign!(Weight);
|
||||||
|
@ -268,6 +274,7 @@ impl<'a> Arbitrary<'a> for Weight {
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
use core::num::NonZeroU64;
|
||||||
|
|
||||||
const ONE: Weight = Weight::from_wu(1);
|
const ONE: Weight = Weight::from_wu(1);
|
||||||
const TWO: Weight = Weight::from_wu(2);
|
const TWO: Weight = Weight::from_wu(2);
|
||||||
|
@ -278,6 +285,17 @@ mod tests {
|
||||||
assert_eq!(Weight::MIN_TRANSACTION, Weight::from_wu(240));
|
assert_eq!(Weight::MIN_TRANSACTION, Weight::from_wu(240));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
#[allow(clippy::op_ref)]
|
||||||
|
fn weight_div_nonzero() {
|
||||||
|
let w = Weight::from_wu(100);
|
||||||
|
let divisor = NonZeroU64::new(4).unwrap();
|
||||||
|
assert_eq!(w / divisor, Weight::from_wu(25));
|
||||||
|
// for borrowed variants
|
||||||
|
assert_eq!(&w / &divisor, Weight::from_wu(25));
|
||||||
|
assert_eq!(w / &divisor, Weight::from_wu(25));
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn from_kwu() {
|
fn from_kwu() {
|
||||||
let got = Weight::from_kwu(1).unwrap();
|
let got = Weight::from_kwu(1).unwrap();
|
||||||
|
|
Loading…
Reference in New Issue