Merge rust-bitcoin/rust-bitcoin#4389: Create impl_mul_assign and impl_div_assign macros
a92cc71f65
Create impl_mul_assign and impl_div_assign macros (Shing Him Ng)
Pull request description:
The macros were called on type-rhs pairs that have an existing implementation of ops::Mul and ops::Div, respectively, that have an `Output` of `Self`
Not as many types as I would have thought, but most of the operations result in a `NumOpResult`, which can't be then assigned back to the variable.
Closes #4172
ACKs for top commit:
apoelstra:
ACK a92cc71f658771776557ea0a40d1d095d3b6d482; successfully ran local tests
Tree-SHA512: 30cfb077b9ba65af991eb17fa05ffc4a870c3f4ded746355d3a8577a71fe9a569588a882c2a936edcc9c88feede4d8bb1379a998e3f330894084a4e2fc434e6e
This commit is contained in:
commit
12cef1d16b
|
@ -8,6 +8,7 @@ use NumOpResult as R;
|
|||
|
||||
use super::{Amount, SignedAmount};
|
||||
use crate::{MathOp, NumOpError, NumOpResult, OptionExt};
|
||||
use crate::internal_macros::{impl_mul_assign, impl_div_assign};
|
||||
|
||||
impl From<Amount> for NumOpResult<Amount> {
|
||||
fn from(a: Amount) -> Self { Self::Valid(a) }
|
||||
|
@ -230,6 +231,11 @@ crate::internal_macros::impl_op_for_references! {
|
|||
}
|
||||
}
|
||||
|
||||
impl_mul_assign!(NumOpResult<Amount>, u64);
|
||||
impl_mul_assign!(NumOpResult<SignedAmount>, i64);
|
||||
impl_div_assign!(NumOpResult<Amount>, u64);
|
||||
impl_div_assign!(NumOpResult<SignedAmount>, i64);
|
||||
|
||||
impl ops::Neg for SignedAmount {
|
||||
type Output = Self;
|
||||
|
||||
|
|
|
@ -23,6 +23,16 @@ fn sat(sat: u64) -> Amount { Amount::from_sat(sat).unwrap() }
|
|||
#[track_caller]
|
||||
fn ssat(ssat: i64) -> SignedAmount { SignedAmount::from_sat(ssat).unwrap() }
|
||||
|
||||
#[track_caller]
|
||||
fn res(n_sat: u64) -> NumOpResult<Amount>{
|
||||
NumOpResult::from(sat(n_sat))
|
||||
}
|
||||
|
||||
#[track_caller]
|
||||
fn sres(n_sat: i64) -> NumOpResult<SignedAmount>{
|
||||
NumOpResult::from(ssat(n_sat))
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn sanity_check() {
|
||||
assert_eq!(ssat(-100).abs(), ssat(100));
|
||||
|
@ -1191,9 +1201,6 @@ fn signed_subtraction() {
|
|||
|
||||
#[test]
|
||||
fn op_int_combos() {
|
||||
let res = |n_sat| NumOpResult::from(sat(n_sat));
|
||||
let sres = |n_ssat| NumOpResult::from(ssat(n_ssat));
|
||||
|
||||
assert_eq!(sat(23) * 31, res(713));
|
||||
assert_eq!(ssat(23) * 31, sres(713));
|
||||
assert_eq!(res(23) * 31, res(713));
|
||||
|
@ -1257,6 +1264,40 @@ fn signed_amount_div_by_amount_zero() {
|
|||
assert!(res.into_result().is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn mul_assign() {
|
||||
let mut result = res(113);
|
||||
result *= 367;
|
||||
assert_eq!(result, res(41471));
|
||||
|
||||
let mut max = res(Amount::MAX.to_sat());
|
||||
max *= 2;
|
||||
assert!(max.is_error());
|
||||
|
||||
let mut signed_result = sres(-211);
|
||||
signed_result *= 431;
|
||||
assert_eq!(signed_result, sres(-90941));
|
||||
|
||||
let mut min = sres(SignedAmount::MIN.to_sat());
|
||||
min *= 2;
|
||||
assert!(min.is_error());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn div_assign() {
|
||||
let mut result = res(41471);
|
||||
result /= 367;
|
||||
assert_eq!(result, res(113));
|
||||
result /= 0;
|
||||
assert!(result.is_error());
|
||||
|
||||
let mut signed_result = sres(-90941);
|
||||
signed_result /= 211;
|
||||
assert_eq!(signed_result, sres(-431));
|
||||
signed_result /= 0;
|
||||
assert!(signed_result.is_error());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn check_const() {
|
||||
assert_eq!(SignedAmount::ONE_BTC.to_sat(), 100_000_000);
|
||||
|
|
|
@ -96,3 +96,31 @@ macro_rules! impl_sub_assign {
|
|||
};
|
||||
}
|
||||
pub(crate) use impl_sub_assign;
|
||||
|
||||
/// Implement `ops::MulAssign` for `$ty` multiplied by `$rhs` and `&$rhs`.
|
||||
macro_rules! impl_mul_assign {
|
||||
($ty:ty, $rhs:ident) => {
|
||||
impl core::ops::MulAssign<$rhs> for $ty {
|
||||
fn mul_assign(&mut self, rhs: $rhs) { *self = *self * rhs }
|
||||
}
|
||||
|
||||
impl core::ops::MulAssign<&$rhs> for $ty {
|
||||
fn mul_assign(&mut self, rhs: &$rhs) { *self = *self * *rhs }
|
||||
}
|
||||
};
|
||||
}
|
||||
pub(crate) use impl_mul_assign;
|
||||
|
||||
/// Implement `ops::DivAssign` for `$ty` divided by `$rhs` and `&$rhs`.
|
||||
macro_rules! impl_div_assign {
|
||||
($ty:ty, $rhs:ident) => {
|
||||
impl core::ops::DivAssign<$rhs> for $ty {
|
||||
fn div_assign(&mut self, rhs: $rhs) { *self = *self / rhs }
|
||||
}
|
||||
|
||||
impl core::ops::DivAssign<&$rhs> for $ty {
|
||||
fn div_assign(&mut self, rhs: &$rhs) { *self = *self / *rhs }
|
||||
}
|
||||
};
|
||||
}
|
||||
pub(crate) use impl_div_assign;
|
||||
|
|
Loading…
Reference in New Issue