Merge rust-bitcoin/rust-bitcoin#4076: units: macroize the op implementations
814685e551
Macroise the NumOpResult tests (Tobin C. Harding)a44a9d31f6
Add a few impls to the result macro (Andrew Poelstra)353c23fa01
units: pull generic op impls on NumOpResult into macro (Andrew Poelstra)21ac5aefe0
units: extend op reference macro to handle generics and where clauses (Andrew Poelstra)ad9564895b
units: replace a gazillion more macro calls with new macro (Andrew Poelstra)0dc7f6cebd
units: rearrange a bit of code to prep the next commit (Andrew Poelstra)a358e79a85
units: allow multiple invocations in impl_op_for_references macro (Andrew Poelstra)2da332e04a
units: introduce impl_op_for_references and use it in three places (Andrew Poelstra)c90559de8e
Derive Copy for NumOpResult (Tobin C. Harding) Pull request description: This introduces a general macro which takes some number of `impl ops::Whatever<A> for <B>` and replicates them with all the permutations of references. It also takes a syntax which resembles the code for the initial impl block. Uses it for all the binary opcodes on `Amount`, `SignedAmount`, `Weight`, `FeeRate`, as well as the numeric mul/div on those types, as well as generic impls on `NumResultOp<T>` (which are expanded to cover more cases). ACKs for top commit: tcharding: ACK814685e551
Tree-SHA512: 6b2ec389373ad50af6681f18fa13b3892bdee953541e6b854d187e6f49ec5e924aae812d4f0ad121f1ff34566161ebea3ce34f2aa87f3f3bda74a5af970add70
This commit is contained in:
commit
d889767273
|
@ -12,7 +12,7 @@ use super::{Amount, SignedAmount};
|
||||||
/// Result of an operation on [`Amount`] or [`SignedAmount`].
|
/// Result of an operation on [`Amount`] or [`SignedAmount`].
|
||||||
///
|
///
|
||||||
/// The type parameter `T` should be normally `Amout` or `SignedAmount`.
|
/// The type parameter `T` should be normally `Amout` or `SignedAmount`.
|
||||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub enum NumOpResult<T> {
|
pub enum NumOpResult<T> {
|
||||||
/// Result of a successful mathematical operation.
|
/// Result of a successful mathematical operation.
|
||||||
|
@ -123,283 +123,178 @@ impl From<&SignedAmount> for NumOpResult<SignedAmount> {
|
||||||
fn from(a: &SignedAmount) -> Self { Self::Valid(*a) }
|
fn from(a: &SignedAmount) -> Self { Self::Valid(*a) }
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ops::Add for Amount {
|
crate::internal_macros::impl_op_for_references! {
|
||||||
type Output = NumOpResult<Amount>;
|
impl ops::Add<Amount> for Amount {
|
||||||
|
type Output = NumOpResult<Amount>;
|
||||||
|
|
||||||
fn add(self, rhs: Amount) -> Self::Output { self.checked_add(rhs).valid_or_error() }
|
fn add(self, rhs: Amount) -> Self::Output { self.checked_add(rhs).valid_or_error() }
|
||||||
}
|
}
|
||||||
crate::internal_macros::impl_add_for_amount_references!(Amount);
|
impl ops::Add<NumOpResult<Amount>> for Amount {
|
||||||
|
type Output = NumOpResult<Amount>;
|
||||||
|
|
||||||
impl ops::Add<NumOpResult<Amount>> for Amount {
|
fn add(self, rhs: NumOpResult<Amount>) -> Self::Output { rhs.and_then(|a| a + self) }
|
||||||
type Output = NumOpResult<Amount>;
|
}
|
||||||
|
|
||||||
fn add(self, rhs: NumOpResult<Amount>) -> Self::Output { rhs.and_then(|a| a + self) }
|
impl ops::Sub<Amount> for Amount {
|
||||||
}
|
type Output = NumOpResult<Amount>;
|
||||||
impl ops::Add<NumOpResult<Amount>> for &Amount {
|
|
||||||
type Output = NumOpResult<Amount>;
|
|
||||||
|
|
||||||
fn add(self, rhs: NumOpResult<Amount>) -> Self::Output { rhs.and_then(|a| a + self) }
|
fn sub(self, rhs: Amount) -> Self::Output { self.checked_sub(rhs).valid_or_error() }
|
||||||
}
|
}
|
||||||
impl ops::Add<Amount> for NumOpResult<Amount> {
|
impl ops::Sub<NumOpResult<Amount>> for Amount {
|
||||||
type Output = NumOpResult<Amount>;
|
type Output = NumOpResult<Amount>;
|
||||||
|
|
||||||
fn add(self, rhs: Amount) -> Self::Output { rhs + self }
|
fn sub(self, rhs: NumOpResult<Amount>) -> Self::Output {
|
||||||
}
|
match rhs {
|
||||||
impl ops::Add<&Amount> for NumOpResult<Amount> {
|
R::Valid(amount) => self - amount,
|
||||||
type Output = NumOpResult<Amount>;
|
R::Error(_) => rhs,
|
||||||
|
}
|
||||||
fn add(self, rhs: &Amount) -> Self::Output { rhs + self }
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ops::Sub for Amount {
|
|
||||||
type Output = NumOpResult<Amount>;
|
|
||||||
|
|
||||||
fn sub(self, rhs: Amount) -> Self::Output { self.checked_sub(rhs).valid_or_error() }
|
|
||||||
}
|
|
||||||
crate::internal_macros::impl_sub_for_amount_references!(Amount);
|
|
||||||
|
|
||||||
impl ops::Sub<NumOpResult<Amount>> for Amount {
|
|
||||||
type Output = NumOpResult<Amount>;
|
|
||||||
|
|
||||||
fn sub(self, rhs: NumOpResult<Amount>) -> Self::Output {
|
|
||||||
match rhs {
|
|
||||||
R::Valid(amount) => self - amount,
|
|
||||||
R::Error(_) => rhs,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
impl ops::Sub<NumOpResult<Amount>> for &Amount {
|
|
||||||
type Output = NumOpResult<Amount>;
|
|
||||||
|
|
||||||
fn sub(self, rhs: NumOpResult<Amount>) -> Self::Output {
|
impl ops::Mul<u64> for Amount {
|
||||||
match rhs {
|
type Output = NumOpResult<Amount>;
|
||||||
R::Valid(amount) => self - amount,
|
|
||||||
R::Error(_) => rhs,
|
fn mul(self, rhs: u64) -> Self::Output { self.checked_mul(rhs).valid_or_error() }
|
||||||
|
}
|
||||||
|
impl ops::Mul<u64> for NumOpResult<Amount> {
|
||||||
|
type Output = NumOpResult<Amount>;
|
||||||
|
|
||||||
|
fn mul(self, rhs: u64) -> Self::Output { self.and_then(|lhs| lhs * rhs) }
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ops::Div<u64> for Amount {
|
||||||
|
type Output = NumOpResult<Amount>;
|
||||||
|
|
||||||
|
fn div(self, rhs: u64) -> Self::Output { self.checked_div(rhs).valid_or_error() }
|
||||||
|
}
|
||||||
|
impl ops::Div<u64> for NumOpResult<Amount> {
|
||||||
|
type Output = NumOpResult<Amount>;
|
||||||
|
|
||||||
|
fn div(self, rhs: u64) -> Self::Output { self.and_then(|lhs| lhs / rhs) }
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ops::Rem<u64> for Amount {
|
||||||
|
type Output = NumOpResult<Amount>;
|
||||||
|
|
||||||
|
fn rem(self, modulus: u64) -> Self::Output { self.checked_rem(modulus).valid_or_error() }
|
||||||
|
}
|
||||||
|
impl ops::Rem<u64> for NumOpResult<Amount> {
|
||||||
|
type Output = NumOpResult<Amount>;
|
||||||
|
|
||||||
|
fn rem(self, modulus: u64) -> Self::Output { self.and_then(|lhs| lhs % modulus) }
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ops::Add<SignedAmount> for SignedAmount {
|
||||||
|
type Output = NumOpResult<SignedAmount>;
|
||||||
|
|
||||||
|
fn add(self, rhs: SignedAmount) -> Self::Output { self.checked_add(rhs).valid_or_error() }
|
||||||
|
}
|
||||||
|
impl ops::Add<NumOpResult<SignedAmount>> for SignedAmount {
|
||||||
|
type Output = NumOpResult<SignedAmount>;
|
||||||
|
|
||||||
|
fn add(self, rhs: NumOpResult<SignedAmount>) -> Self::Output { rhs.and_then(|a| a + self) }
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ops::Sub<SignedAmount> for SignedAmount {
|
||||||
|
type Output = NumOpResult<SignedAmount>;
|
||||||
|
|
||||||
|
fn sub(self, rhs: SignedAmount) -> Self::Output { self.checked_sub(rhs).valid_or_error() }
|
||||||
|
}
|
||||||
|
impl ops::Sub<NumOpResult<SignedAmount>> for SignedAmount {
|
||||||
|
type Output = NumOpResult<SignedAmount>;
|
||||||
|
|
||||||
|
fn sub(self, rhs: NumOpResult<SignedAmount>) -> Self::Output {
|
||||||
|
match rhs {
|
||||||
|
R::Valid(amount) => self - amount,
|
||||||
|
R::Error(_) => rhs,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
impl ops::Sub<Amount> for NumOpResult<Amount> {
|
|
||||||
type Output = NumOpResult<Amount>;
|
|
||||||
|
|
||||||
fn sub(self, rhs: Amount) -> Self::Output {
|
impl ops::Mul<i64> for SignedAmount {
|
||||||
match self {
|
type Output = NumOpResult<SignedAmount>;
|
||||||
R::Valid(amount) => amount - rhs,
|
|
||||||
R::Error(_) => self,
|
fn mul(self, rhs: i64) -> Self::Output { self.checked_mul(rhs).valid_or_error() }
|
||||||
|
}
|
||||||
|
impl ops::Mul<i64> for NumOpResult<SignedAmount> {
|
||||||
|
type Output = NumOpResult<SignedAmount>;
|
||||||
|
|
||||||
|
fn mul(self, rhs: i64) -> Self::Output { self.and_then(|lhs| lhs * rhs) }
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ops::Div<i64> for SignedAmount {
|
||||||
|
type Output = NumOpResult<SignedAmount>;
|
||||||
|
|
||||||
|
fn div(self, rhs: i64) -> Self::Output { self.checked_div(rhs).valid_or_error() }
|
||||||
|
}
|
||||||
|
impl ops::Div<i64> for NumOpResult<SignedAmount> {
|
||||||
|
type Output = NumOpResult<SignedAmount>;
|
||||||
|
|
||||||
|
fn div(self, rhs: i64) -> Self::Output { self.and_then(|lhs| lhs / rhs) }
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ops::Rem<i64> for SignedAmount {
|
||||||
|
type Output = NumOpResult<SignedAmount>;
|
||||||
|
|
||||||
|
fn rem(self, modulus: i64) -> Self::Output { self.checked_rem(modulus).valid_or_error() }
|
||||||
|
}
|
||||||
|
impl ops::Rem<i64> for NumOpResult<SignedAmount> {
|
||||||
|
type Output = NumOpResult<SignedAmount>;
|
||||||
|
|
||||||
|
fn rem(self, modulus: i64) -> Self::Output { self.and_then(|lhs| lhs % modulus) }
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> ops::Add<NumOpResult<T>> for NumOpResult<T>
|
||||||
|
where
|
||||||
|
(T: Copy + ops::Add<Output = NumOpResult<T>>)
|
||||||
|
{
|
||||||
|
type Output = NumOpResult<T>;
|
||||||
|
|
||||||
|
fn add(self, rhs: Self) -> Self::Output {
|
||||||
|
match (self, rhs) {
|
||||||
|
(R::Valid(lhs), R::Valid(rhs)) => lhs + rhs,
|
||||||
|
(_, _) => R::Error(NumOpError {}),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
impl ops::Sub<&Amount> for NumOpResult<Amount> {
|
|
||||||
type Output = NumOpResult<Amount>;
|
|
||||||
|
|
||||||
fn sub(self, rhs: &Amount) -> Self::Output {
|
impl<T> ops::Add<T> for NumOpResult<T>
|
||||||
match self {
|
where
|
||||||
R::Valid(amount) => amount - (*rhs),
|
(T: Copy + ops::Add<NumOpResult<T>, Output = NumOpResult<T>>)
|
||||||
R::Error(_) => self,
|
{
|
||||||
|
type Output = NumOpResult<T>;
|
||||||
|
|
||||||
|
fn add(self, rhs: T) -> Self::Output { rhs + self }
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> ops::Sub<NumOpResult<T>> for NumOpResult<T>
|
||||||
|
where
|
||||||
|
(T: Copy + ops::Sub<Output = NumOpResult<T>>)
|
||||||
|
{
|
||||||
|
type Output = NumOpResult<T>;
|
||||||
|
|
||||||
|
fn sub(self, rhs: Self) -> Self::Output {
|
||||||
|
match (self, rhs) {
|
||||||
|
(R::Valid(lhs), R::Valid(rhs)) => lhs - rhs,
|
||||||
|
(_, _) => R::Error(NumOpError {}),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
impl ops::Mul<u64> for Amount {
|
impl<T> ops::Sub<T> for NumOpResult<T>
|
||||||
type Output = NumOpResult<Amount>;
|
where
|
||||||
|
(T: Copy + ops::Sub<Output = NumOpResult<T>>)
|
||||||
|
{
|
||||||
|
type Output = NumOpResult<T>;
|
||||||
|
|
||||||
fn mul(self, rhs: u64) -> Self::Output { self.checked_mul(rhs).valid_or_error() }
|
fn sub(self, rhs: T) -> Self::Output {
|
||||||
}
|
match self {
|
||||||
impl ops::Mul<&u64> for Amount {
|
R::Valid(amount) => amount - rhs,
|
||||||
type Output = NumOpResult<Amount>;
|
R::Error(_) => self,
|
||||||
|
}
|
||||||
fn mul(self, rhs: &u64) -> Self::Output { self.mul(*rhs) }
|
|
||||||
}
|
|
||||||
impl ops::Mul<u64> for &Amount {
|
|
||||||
type Output = NumOpResult<Amount>;
|
|
||||||
|
|
||||||
fn mul(self, rhs: u64) -> Self::Output { (*self).mul(rhs) }
|
|
||||||
}
|
|
||||||
impl ops::Mul<&u64> for &Amount {
|
|
||||||
type Output = NumOpResult<Amount>;
|
|
||||||
|
|
||||||
fn mul(self, rhs: &u64) -> Self::Output { self.mul(*rhs) }
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ops::Div<u64> for Amount {
|
|
||||||
type Output = NumOpResult<Amount>;
|
|
||||||
|
|
||||||
fn div(self, rhs: u64) -> Self::Output { self.checked_div(rhs).valid_or_error() }
|
|
||||||
}
|
|
||||||
impl ops::Div<&u64> for Amount {
|
|
||||||
type Output = NumOpResult<Amount>;
|
|
||||||
|
|
||||||
fn div(self, rhs: &u64) -> Self::Output { self.div(*rhs) }
|
|
||||||
}
|
|
||||||
impl ops::Div<u64> for &Amount {
|
|
||||||
type Output = NumOpResult<Amount>;
|
|
||||||
|
|
||||||
fn div(self, rhs: u64) -> Self::Output { (*self).div(rhs) }
|
|
||||||
}
|
|
||||||
impl ops::Div<&u64> for &Amount {
|
|
||||||
type Output = NumOpResult<Amount>;
|
|
||||||
|
|
||||||
fn div(self, rhs: &u64) -> Self::Output { (*self).div(*rhs) }
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ops::Rem<u64> for Amount {
|
|
||||||
type Output = NumOpResult<Amount>;
|
|
||||||
|
|
||||||
fn rem(self, modulus: u64) -> Self::Output { self.checked_rem(modulus).valid_or_error() }
|
|
||||||
}
|
|
||||||
impl ops::Rem<&u64> for Amount {
|
|
||||||
type Output = NumOpResult<Amount>;
|
|
||||||
|
|
||||||
fn rem(self, modulus: &u64) -> Self::Output { self.rem(*modulus) }
|
|
||||||
}
|
|
||||||
impl ops::Rem<u64> for &Amount {
|
|
||||||
type Output = NumOpResult<Amount>;
|
|
||||||
|
|
||||||
fn rem(self, modulus: u64) -> Self::Output { (*self).rem(modulus) }
|
|
||||||
}
|
|
||||||
impl ops::Rem<&u64> for &Amount {
|
|
||||||
type Output = NumOpResult<Amount>;
|
|
||||||
|
|
||||||
fn rem(self, modulus: &u64) -> Self::Output { (*self).rem(*modulus) }
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ops::Add for SignedAmount {
|
|
||||||
type Output = NumOpResult<SignedAmount>;
|
|
||||||
|
|
||||||
fn add(self, rhs: SignedAmount) -> Self::Output { self.checked_add(rhs).valid_or_error() }
|
|
||||||
}
|
|
||||||
crate::internal_macros::impl_add_for_amount_references!(SignedAmount);
|
|
||||||
|
|
||||||
impl ops::Add<NumOpResult<SignedAmount>> for SignedAmount {
|
|
||||||
type Output = NumOpResult<SignedAmount>;
|
|
||||||
|
|
||||||
fn add(self, rhs: NumOpResult<SignedAmount>) -> Self::Output { rhs.and_then(|a| a + self) }
|
|
||||||
}
|
|
||||||
impl ops::Add<NumOpResult<SignedAmount>> for &SignedAmount {
|
|
||||||
type Output = NumOpResult<SignedAmount>;
|
|
||||||
|
|
||||||
fn add(self, rhs: NumOpResult<SignedAmount>) -> Self::Output { rhs.and_then(|a| a + self) }
|
|
||||||
}
|
|
||||||
impl ops::Add<SignedAmount> for NumOpResult<SignedAmount> {
|
|
||||||
type Output = NumOpResult<SignedAmount>;
|
|
||||||
|
|
||||||
fn add(self, rhs: SignedAmount) -> Self::Output { rhs + self }
|
|
||||||
}
|
|
||||||
impl ops::Add<&SignedAmount> for NumOpResult<SignedAmount> {
|
|
||||||
type Output = NumOpResult<SignedAmount>;
|
|
||||||
|
|
||||||
fn add(self, rhs: &SignedAmount) -> Self::Output { rhs + self }
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ops::Sub for SignedAmount {
|
|
||||||
type Output = NumOpResult<SignedAmount>;
|
|
||||||
|
|
||||||
fn sub(self, rhs: SignedAmount) -> Self::Output { self.checked_sub(rhs).valid_or_error() }
|
|
||||||
}
|
|
||||||
crate::internal_macros::impl_sub_for_amount_references!(SignedAmount);
|
|
||||||
|
|
||||||
impl ops::Sub<NumOpResult<SignedAmount>> for SignedAmount {
|
|
||||||
type Output = NumOpResult<SignedAmount>;
|
|
||||||
|
|
||||||
fn sub(self, rhs: NumOpResult<SignedAmount>) -> Self::Output {
|
|
||||||
match rhs {
|
|
||||||
R::Valid(amount) => amount - rhs,
|
|
||||||
R::Error(_) => rhs,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl ops::Sub<NumOpResult<SignedAmount>> for &SignedAmount {
|
|
||||||
type Output = NumOpResult<SignedAmount>;
|
|
||||||
|
|
||||||
fn sub(self, rhs: NumOpResult<SignedAmount>) -> Self::Output {
|
|
||||||
match rhs {
|
|
||||||
R::Valid(amount) => amount - rhs,
|
|
||||||
R::Error(_) => rhs,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
impl ops::Sub<SignedAmount> for NumOpResult<SignedAmount> {
|
|
||||||
type Output = NumOpResult<SignedAmount>;
|
|
||||||
|
|
||||||
fn sub(self, rhs: SignedAmount) -> Self::Output {
|
|
||||||
match self {
|
|
||||||
R::Valid(amount) => amount - rhs,
|
|
||||||
R::Error(_) => self,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
impl ops::Sub<&SignedAmount> for NumOpResult<SignedAmount> {
|
|
||||||
type Output = NumOpResult<SignedAmount>;
|
|
||||||
|
|
||||||
fn sub(self, rhs: &SignedAmount) -> Self::Output {
|
|
||||||
match self {
|
|
||||||
R::Valid(amount) => amount - *rhs,
|
|
||||||
R::Error(_) => self,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ops::Mul<i64> for SignedAmount {
|
|
||||||
type Output = NumOpResult<SignedAmount>;
|
|
||||||
|
|
||||||
fn mul(self, rhs: i64) -> Self::Output { self.checked_mul(rhs).valid_or_error() }
|
|
||||||
}
|
|
||||||
impl ops::Mul<&i64> for SignedAmount {
|
|
||||||
type Output = NumOpResult<SignedAmount>;
|
|
||||||
|
|
||||||
fn mul(self, rhs: &i64) -> Self::Output { self.mul(*rhs) }
|
|
||||||
}
|
|
||||||
impl ops::Mul<i64> for &SignedAmount {
|
|
||||||
type Output = NumOpResult<SignedAmount>;
|
|
||||||
|
|
||||||
fn mul(self, rhs: i64) -> Self::Output { (*self).mul(rhs) }
|
|
||||||
}
|
|
||||||
impl ops::Mul<&i64> for &SignedAmount {
|
|
||||||
type Output = NumOpResult<SignedAmount>;
|
|
||||||
|
|
||||||
fn mul(self, rhs: &i64) -> Self::Output { self.mul(*rhs) }
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ops::Div<i64> for SignedAmount {
|
|
||||||
type Output = NumOpResult<SignedAmount>;
|
|
||||||
|
|
||||||
fn div(self, rhs: i64) -> Self::Output { self.checked_div(rhs).valid_or_error() }
|
|
||||||
}
|
|
||||||
impl ops::Div<&i64> for SignedAmount {
|
|
||||||
type Output = NumOpResult<SignedAmount>;
|
|
||||||
|
|
||||||
fn div(self, rhs: &i64) -> Self::Output { self.div(*rhs) }
|
|
||||||
}
|
|
||||||
impl ops::Div<i64> for &SignedAmount {
|
|
||||||
type Output = NumOpResult<SignedAmount>;
|
|
||||||
|
|
||||||
fn div(self, rhs: i64) -> Self::Output { (*self).div(rhs) }
|
|
||||||
}
|
|
||||||
impl ops::Div<&i64> for &SignedAmount {
|
|
||||||
type Output = NumOpResult<SignedAmount>;
|
|
||||||
|
|
||||||
fn div(self, rhs: &i64) -> Self::Output { (*self).div(*rhs) }
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ops::Rem<i64> for SignedAmount {
|
|
||||||
type Output = NumOpResult<SignedAmount>;
|
|
||||||
|
|
||||||
fn rem(self, modulus: i64) -> Self::Output { self.checked_rem(modulus).valid_or_error() }
|
|
||||||
}
|
|
||||||
impl ops::Rem<&i64> for SignedAmount {
|
|
||||||
type Output = NumOpResult<SignedAmount>;
|
|
||||||
|
|
||||||
fn rem(self, modulus: &i64) -> Self::Output { self.rem(*modulus) }
|
|
||||||
}
|
|
||||||
impl ops::Rem<i64> for &SignedAmount {
|
|
||||||
type Output = NumOpResult<SignedAmount>;
|
|
||||||
|
|
||||||
fn rem(self, modulus: i64) -> Self::Output { (*self).rem(modulus) }
|
|
||||||
}
|
|
||||||
impl ops::Rem<&i64> for &SignedAmount {
|
|
||||||
type Output = NumOpResult<SignedAmount>;
|
|
||||||
|
|
||||||
fn rem(self, modulus: &i64) -> Self::Output { (*self).rem(*modulus) }
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ops::Neg for SignedAmount {
|
impl ops::Neg for SignedAmount {
|
||||||
type Output = Self;
|
type Output = Self;
|
||||||
|
@ -407,112 +302,6 @@ impl ops::Neg for SignedAmount {
|
||||||
fn neg(self) -> Self::Output { Self::from_sat(self.to_sat().neg()) }
|
fn neg(self) -> Self::Output { Self::from_sat(self.to_sat().neg()) }
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> ops::Add for NumOpResult<T>
|
|
||||||
where
|
|
||||||
T: ops::Add<Output = NumOpResult<T>>,
|
|
||||||
{
|
|
||||||
type Output = NumOpResult<T>;
|
|
||||||
|
|
||||||
fn add(self, rhs: Self) -> Self::Output {
|
|
||||||
match (self, rhs) {
|
|
||||||
(R::Valid(lhs), R::Valid(rhs)) => lhs + rhs,
|
|
||||||
(_, _) => R::Error(NumOpError {}),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
impl<T> ops::Add<NumOpResult<T>> for &NumOpResult<T>
|
|
||||||
where
|
|
||||||
T: ops::Add<Output = NumOpResult<T>> + Copy,
|
|
||||||
{
|
|
||||||
type Output = NumOpResult<T>;
|
|
||||||
|
|
||||||
fn add(self, rhs: NumOpResult<T>) -> Self::Output {
|
|
||||||
match (self, rhs) {
|
|
||||||
(R::Valid(lhs), R::Valid(rhs)) => *lhs + rhs,
|
|
||||||
(_, _) => R::Error(NumOpError {}),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
impl<T> ops::Add<&NumOpResult<T>> for NumOpResult<T>
|
|
||||||
where
|
|
||||||
T: ops::Add<Output = NumOpResult<T>> + Copy,
|
|
||||||
{
|
|
||||||
type Output = NumOpResult<T>;
|
|
||||||
|
|
||||||
fn add(self, rhs: &NumOpResult<T>) -> Self::Output {
|
|
||||||
match (self, rhs) {
|
|
||||||
(R::Valid(lhs), R::Valid(rhs)) => lhs + *rhs,
|
|
||||||
(_, _) => R::Error(NumOpError {}),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
impl<T> ops::Add for &NumOpResult<T>
|
|
||||||
where
|
|
||||||
T: ops::Add<Output = NumOpResult<T>> + Copy,
|
|
||||||
{
|
|
||||||
type Output = NumOpResult<T>;
|
|
||||||
|
|
||||||
fn add(self, rhs: &NumOpResult<T>) -> Self::Output {
|
|
||||||
match (self, rhs) {
|
|
||||||
(R::Valid(lhs), R::Valid(rhs)) => *lhs + *rhs,
|
|
||||||
(_, _) => R::Error(NumOpError {}),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T> ops::Sub for NumOpResult<T>
|
|
||||||
where
|
|
||||||
T: ops::Sub<Output = NumOpResult<T>>,
|
|
||||||
{
|
|
||||||
type Output = NumOpResult<T>;
|
|
||||||
|
|
||||||
fn sub(self, rhs: Self) -> Self::Output {
|
|
||||||
match (self, rhs) {
|
|
||||||
(R::Valid(lhs), R::Valid(rhs)) => lhs - rhs,
|
|
||||||
(_, _) => R::Error(NumOpError {}),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
impl<T> ops::Sub<NumOpResult<T>> for &NumOpResult<T>
|
|
||||||
where
|
|
||||||
T: ops::Sub<Output = NumOpResult<T>> + Copy,
|
|
||||||
{
|
|
||||||
type Output = NumOpResult<T>;
|
|
||||||
|
|
||||||
fn sub(self, rhs: NumOpResult<T>) -> Self::Output {
|
|
||||||
match (self, rhs) {
|
|
||||||
(R::Valid(lhs), R::Valid(rhs)) => *lhs - rhs,
|
|
||||||
(_, _) => R::Error(NumOpError {}),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
impl<T> ops::Sub<&NumOpResult<T>> for NumOpResult<T>
|
|
||||||
where
|
|
||||||
T: ops::Sub<Output = NumOpResult<T>> + Copy,
|
|
||||||
{
|
|
||||||
type Output = NumOpResult<T>;
|
|
||||||
|
|
||||||
fn sub(self, rhs: &NumOpResult<T>) -> Self::Output {
|
|
||||||
match (self, rhs) {
|
|
||||||
(R::Valid(lhs), R::Valid(rhs)) => lhs - *rhs,
|
|
||||||
(_, _) => R::Error(NumOpError {}),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
impl<T> ops::Sub for &NumOpResult<T>
|
|
||||||
where
|
|
||||||
T: ops::Sub<Output = NumOpResult<T>> + Copy,
|
|
||||||
{
|
|
||||||
type Output = NumOpResult<T>;
|
|
||||||
|
|
||||||
fn sub(self, rhs: Self) -> Self::Output {
|
|
||||||
match (self, rhs) {
|
|
||||||
(R::Valid(lhs), R::Valid(rhs)) => *lhs - *rhs,
|
|
||||||
(_, _) => R::Error(NumOpError {}),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl core::iter::Sum<NumOpResult<Amount>> for NumOpResult<Amount> {
|
impl core::iter::Sum<NumOpResult<Amount>> for NumOpResult<Amount> {
|
||||||
fn sum<I>(iter: I) -> Self
|
fn sum<I>(iter: I) -> Self
|
||||||
where
|
where
|
||||||
|
@ -584,7 +373,7 @@ impl OptionExt<SignedAmount> for Option<SignedAmount> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// An error occurred while doing a mathematical operation.
|
/// An error occurred while doing a mathematical operation.
|
||||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
|
||||||
#[non_exhaustive]
|
#[non_exhaustive]
|
||||||
pub struct NumOpError;
|
pub struct NumOpError;
|
||||||
|
|
||||||
|
|
|
@ -1196,184 +1196,133 @@ fn check_const() {
|
||||||
assert_eq!(Amount::MAX_MONEY.to_sat() as i64, SignedAmount::MAX_MONEY.to_sat());
|
assert_eq!(Amount::MAX_MONEY.to_sat() as i64, SignedAmount::MAX_MONEY.to_sat());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Verify we have implemented all combinations of ops for `Amount` and `SignedAmount`.
|
// Sanity check than stdlib supports the set of reference combinations for the ops we want.
|
||||||
// It's easier to read this test that check the code.
|
|
||||||
#[test]
|
#[test]
|
||||||
#[allow(clippy::op_ref)] // We are explicitly testing the references work with ops.
|
#[allow(clippy::op_ref)] // We are explicitly testing the references work with ops.
|
||||||
fn amount_tyes_all_ops() {
|
fn sanity_all_ops() {
|
||||||
// Sanity check than stdlib supports the set of reference combinations for the ops we want.
|
let x = 127;
|
||||||
{
|
|
||||||
let x = 127;
|
|
||||||
|
|
||||||
let _ = x + x;
|
let _ = x + x;
|
||||||
let _ = &x + x;
|
let _ = &x + x;
|
||||||
let _ = x + &x;
|
let _ = x + &x;
|
||||||
let _ = &x + &x;
|
let _ = &x + &x;
|
||||||
|
|
||||||
let _ = x - x;
|
let _ = x - x;
|
||||||
let _ = &x - x;
|
let _ = &x - x;
|
||||||
let _ = x - &x;
|
let _ = x - &x;
|
||||||
let _ = &x - &x;
|
let _ = &x - &x;
|
||||||
|
|
||||||
let _ = -x;
|
let _ = -x;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Verify we have implemented all combinations of ops for the amount types and `NumOpResult` type.
|
||||||
|
// It's easier to read this test than check the code.
|
||||||
|
#[test]
|
||||||
|
#[allow(clippy::op_ref)] // We are explicitly testing the references work with ops.
|
||||||
|
fn num_op_result_ops() {
|
||||||
let sat = Amount::from_sat(1);
|
let sat = Amount::from_sat(1);
|
||||||
let ssat = SignedAmount::from_sat(1);
|
let ssat = SignedAmount::from_sat(1);
|
||||||
|
|
||||||
// Add
|
// Explicit type as sanity check.
|
||||||
let _ = sat + sat;
|
let res: NumOpResult<Amount> = sat + sat;
|
||||||
let _ = &sat + sat;
|
let sres: NumOpResult<SignedAmount> = ssat + ssat;
|
||||||
let _ = sat + &sat;
|
|
||||||
let _ = &sat + &sat;
|
|
||||||
|
|
||||||
// let _ = ssat + sat;
|
macro_rules! check_op {
|
||||||
// let _ = &ssat + sat;
|
($(let _ = $lhs:ident $op:tt $rhs:ident);* $(;)?) => {
|
||||||
// let _ = ssat + &sat;
|
$(
|
||||||
// let _ = &ssat + &sat;
|
let _ = $lhs $op $rhs;
|
||||||
|
let _ = &$lhs $op $rhs;
|
||||||
|
let _ = $lhs $op &$rhs;
|
||||||
|
let _ = &$lhs $op &$rhs;
|
||||||
|
)*
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// let _ = sat + ssat;
|
// We do not currently support division involving `NumOpResult` and an amount type.
|
||||||
// let _ = &sat + ssat;
|
check_op! {
|
||||||
// let _ = sat + &ssat;
|
// Operations where RHS is the result of another operation.
|
||||||
// let _ = &sat + &ssat;
|
let _ = sat + res;
|
||||||
|
let _ = sat - res;
|
||||||
|
// let _ = sat / res;
|
||||||
|
let _ = ssat + sres;
|
||||||
|
let _ = ssat - sres;
|
||||||
|
// let _ = ssat / sres;
|
||||||
|
|
||||||
let _ = ssat + ssat;
|
// Operations where LHS is the result of another operation.
|
||||||
let _ = &ssat + ssat;
|
let _ = res + sat;
|
||||||
let _ = ssat + &ssat;
|
let _ = res - sat;
|
||||||
let _ = &ssat + &ssat;
|
// let _ = res / sat;
|
||||||
|
let _ = sres + ssat;
|
||||||
|
let _ = sres - ssat;
|
||||||
|
// let _ = sres / ssat;
|
||||||
|
|
||||||
// Sub
|
// Operations that where both sides are the result of another operation.
|
||||||
let _ = sat - sat;
|
let _ = res + res;
|
||||||
let _ = &sat - sat;
|
let _ = res - res;
|
||||||
let _ = sat - &sat;
|
// let _ = res / res;
|
||||||
let _ = &sat - &sat;
|
let _ = sres + sres;
|
||||||
|
let _ = sres - sres;
|
||||||
// let _ = ssat - sat;
|
// let _ = sres / sres;
|
||||||
// let _ = &ssat - sat;
|
};
|
||||||
// let _ = ssat - &sat;
|
|
||||||
// let _ = &ssat - &sat;
|
|
||||||
|
|
||||||
// let _ = sat - ssat;
|
|
||||||
// let _ = &sat - ssat;
|
|
||||||
// let _ = sat - &ssat;
|
|
||||||
// let _ = &sat - &ssat;
|
|
||||||
|
|
||||||
let _ = ssat - ssat;
|
|
||||||
let _ = &ssat - ssat;
|
|
||||||
let _ = ssat - &ssat;
|
|
||||||
let _ = &ssat - &ssat;
|
|
||||||
|
|
||||||
// let _ = sat * sat; // Intentionally not supported.
|
|
||||||
|
|
||||||
// Mul
|
|
||||||
let _ = sat * 3;
|
|
||||||
let _ = sat * &3;
|
|
||||||
let _ = &sat * 3;
|
|
||||||
let _ = &sat * &3;
|
|
||||||
|
|
||||||
let _ = ssat * 3_i64; // Explicit type for the benefit of the reader.
|
|
||||||
let _ = ssat * &3;
|
|
||||||
let _ = &ssat * 3;
|
|
||||||
let _ = &ssat * &3;
|
|
||||||
|
|
||||||
// Div
|
|
||||||
let _ = sat / 3;
|
|
||||||
let _ = &sat / 3;
|
|
||||||
let _ = sat / &3;
|
|
||||||
let _ = &sat / &3;
|
|
||||||
|
|
||||||
let _ = ssat / 3_i64; // Explicit type for the benefit of the reader.
|
|
||||||
let _ = &ssat / 3;
|
|
||||||
let _ = ssat / &3;
|
|
||||||
let _ = &ssat / &3;
|
|
||||||
|
|
||||||
// Rem
|
|
||||||
let _ = sat % 3;
|
|
||||||
let _ = &sat % 3;
|
|
||||||
let _ = sat % &3;
|
|
||||||
let _ = &sat % &3;
|
|
||||||
|
|
||||||
let _ = ssat % 3;
|
|
||||||
let _ = &ssat % 3;
|
|
||||||
let _ = ssat % &3;
|
|
||||||
let _ = &ssat % &3;
|
|
||||||
|
|
||||||
// FIXME: Do we want to support this?
|
|
||||||
// let _ = sat / sat;
|
|
||||||
//
|
|
||||||
// "How many times does this amount go into that amount?" - seems
|
|
||||||
// like a reasonable question to ask.
|
|
||||||
|
|
||||||
// FIXME: Do we want to support these?
|
|
||||||
// let _ = -sat;
|
|
||||||
// let _ = -ssat;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME: Should we support this sort of thing?
|
// Verify we have implemented all combinations of ops for the `NumOpResult` type and an integer.
|
||||||
// It will be a lot more code for possibly not that much benefit.
|
// It's easier to read this test than check the code.
|
||||||
#[test]
|
|
||||||
fn can_ops_on_amount_and_signed_amount() {
|
|
||||||
// let res: NumOpResult<SignedAmount> = sat + ssat;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Verify we have implemented all combinations of ops for the `NumOpResult` type.
|
|
||||||
// It's easier to read this test that check the code.
|
|
||||||
#[test]
|
#[test]
|
||||||
#[allow(clippy::op_ref)] // We are explicitly testing the references work with ops.
|
#[allow(clippy::op_ref)] // We are explicitly testing the references work with ops.
|
||||||
fn amount_op_result_all_ops() {
|
fn num_op_result_ops_integer() {
|
||||||
let sat = Amount::from_sat(1);
|
let sat = Amount::from_sat(1);
|
||||||
// let ssat = SignedAmount::from_sat(1);
|
let ssat = SignedAmount::from_sat(1);
|
||||||
|
|
||||||
// Explicit type as sanity check.
|
// Explicit type as sanity check.
|
||||||
let res: NumOpResult<Amount> = sat + sat;
|
let res: NumOpResult<Amount> = sat + sat;
|
||||||
// let sres: NumOpResult<SignedAmount> = ssat + ssat;
|
let sres: NumOpResult<SignedAmount> = ssat + ssat;
|
||||||
|
|
||||||
// Operations that where RHS is the result of another operation.
|
macro_rules! check_op {
|
||||||
let _ = sat + res.clone();
|
($(let _ = $lhs:ident $op:tt $rhs:literal);* $(;)?) => {
|
||||||
let _ = &sat + res.clone();
|
$(
|
||||||
// let _ = sat + &res.clone();
|
let _ = $lhs $op $rhs;
|
||||||
// let _ = &sat + &res.clone();
|
let _ = &$lhs $op $rhs;
|
||||||
|
let _ = $lhs $op &$rhs;
|
||||||
|
let _ = &$lhs $op &$rhs;
|
||||||
|
)*
|
||||||
|
}
|
||||||
|
}
|
||||||
|
check_op! {
|
||||||
|
// Operations on a `NumOpResult` and integer.
|
||||||
|
let _ = res * 3_u64; // Explicit type for the benefit of the reader.
|
||||||
|
let _ = res / 3;
|
||||||
|
let _ = res % 3;
|
||||||
|
|
||||||
let _ = sat - res.clone();
|
let _ = sres * 3_i64; // Explicit type for the benefit of the reader.
|
||||||
let _ = &sat - res.clone();
|
let _ = sres / 3;
|
||||||
// let _ = sat - &res.clone();
|
let _ = sres % 3;
|
||||||
// let _ = &sat - &res.clone();
|
};
|
||||||
|
}
|
||||||
|
|
||||||
// Operations that where LHS is the result of another operation.
|
// Verify we have implemented all `Neg` for the amount types.
|
||||||
let _ = res.clone() + sat;
|
#[test]
|
||||||
// let _ = &res.clone() + sat;
|
fn amount_op_result_neg() {
|
||||||
let _ = res.clone() + &sat;
|
// TODO: Implement Neg all round.
|
||||||
// let _ = &res.clone() + &sat;
|
|
||||||
|
|
||||||
let _ = res.clone() - sat;
|
// let sat = Amount::from_sat(1);
|
||||||
// let _ = &res.clone() - sat;
|
let ssat = SignedAmount::from_sat(1);
|
||||||
let _ = res.clone() - &sat;
|
|
||||||
// let _ = &res.clone() - &sat;
|
|
||||||
|
|
||||||
// Operations that where both sides are the result of another operation.
|
// let _ = -sat;
|
||||||
let _ = res.clone() + res.clone();
|
let _ = -ssat;
|
||||||
// let _ = &res.clone() + res.clone();
|
// let _ = -res;
|
||||||
// let _ = res.clone() + &res.clone();
|
// let _ = -sres;
|
||||||
// let _ = &res.clone() + &res.clone();
|
|
||||||
|
|
||||||
let _ = res.clone() - res.clone();
|
|
||||||
// let _ = &res.clone() - res.clone();
|
|
||||||
// let _ = res.clone() - &res.clone();
|
|
||||||
// let _ = &res.clone() - &res.clone();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Verify we have implemented all `Sum` for the `NumOpResult` type.
|
// Verify we have implemented all `Sum` for the `NumOpResult` type.
|
||||||
#[test]
|
#[test]
|
||||||
fn amount_op_result_sum() {
|
fn amount_op_result_sum() {
|
||||||
let res = Amount::from_sat(1) + Amount::from_sat(1);
|
let res = Amount::from_sat(1) + Amount::from_sat(1);
|
||||||
let amounts = [res.clone(), res.clone()];
|
let amounts = [res, res];
|
||||||
let amount_refs = [&res, &res];
|
let amount_refs = [&res, &res];
|
||||||
|
|
||||||
// Sum iterators.
|
// Sum iterators.
|
||||||
let _ = amounts.iter().sum::<NumOpResult<Amount>>();
|
let _ = amounts.iter().sum::<NumOpResult<Amount>>();
|
||||||
let _ = amount_refs.iter().copied().sum::<NumOpResult<Amount>>();
|
let _ = amount_refs.iter().copied().sum::<NumOpResult<Amount>>();
|
||||||
let _ = amount_refs.into_iter().sum::<NumOpResult<Amount>>();
|
let _ = amount_refs.into_iter().sum::<NumOpResult<Amount>>();
|
||||||
|
|
||||||
// FIXME: Should we support this? I don't think so (Tobin).
|
|
||||||
// let _ = amount_refs.iter().sum::<NumOpResult<&Amount>>();
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -135,20 +135,20 @@ impl From<FeeRate> for u64 {
|
||||||
fn from(value: FeeRate) -> Self { value.to_sat_per_kwu() }
|
fn from(value: FeeRate) -> Self { value.to_sat_per_kwu() }
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ops::Add for FeeRate {
|
crate::internal_macros::impl_op_for_references! {
|
||||||
type Output = FeeRate;
|
impl ops::Add<FeeRate> for FeeRate {
|
||||||
|
type Output = FeeRate;
|
||||||
|
|
||||||
fn add(self, rhs: FeeRate) -> Self::Output { FeeRate(self.0 + rhs.0) }
|
fn add(self, rhs: FeeRate) -> Self::Output { FeeRate(self.0 + rhs.0) }
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ops::Sub<FeeRate> for FeeRate {
|
||||||
|
type Output = FeeRate;
|
||||||
|
|
||||||
|
fn sub(self, rhs: FeeRate) -> Self::Output { FeeRate(self.0 - rhs.0) }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
crate::internal_macros::impl_add_for_references!(FeeRate);
|
|
||||||
crate::internal_macros::impl_add_assign!(FeeRate);
|
crate::internal_macros::impl_add_assign!(FeeRate);
|
||||||
|
|
||||||
impl ops::Sub for FeeRate {
|
|
||||||
type Output = FeeRate;
|
|
||||||
|
|
||||||
fn sub(self, rhs: FeeRate) -> Self::Output { FeeRate(self.0 - rhs.0) }
|
|
||||||
}
|
|
||||||
crate::internal_macros::impl_sub_for_references!(FeeRate);
|
|
||||||
crate::internal_macros::impl_sub_assign!(FeeRate);
|
crate::internal_macros::impl_sub_assign!(FeeRate);
|
||||||
|
|
||||||
impl core::iter::Sum for FeeRate {
|
impl core::iter::Sum for FeeRate {
|
||||||
|
|
|
@ -4,65 +4,70 @@
|
||||||
//!
|
//!
|
||||||
//! Macros meant to be used inside the `bitcoin-units` library.
|
//! Macros meant to be used inside the `bitcoin-units` library.
|
||||||
|
|
||||||
/// Implements `ops::Add` for various references.
|
/// Implements an opcode for various reference combinations.
|
||||||
///
|
///
|
||||||
/// Requires `$ty` it implement `Add` e.g. 'impl Add<T> for T'. Adds impls of:
|
/// Given `$ty`, assumes the `$op_trait<$other_ty>` trait is implemented on it,
|
||||||
|
/// and implements the same trait with the full matrix of `&$ty` and `&$other_ty`:
|
||||||
///
|
///
|
||||||
/// - Add<T> for &T
|
/// - `Add<$other_ty> for &$ty`
|
||||||
/// - Add<&T> for T
|
/// - `Add<&$other_ty> for $ty`
|
||||||
/// - Add<&T> for &T
|
/// - `Add<&$other_ty> for &$ty`
|
||||||
macro_rules! impl_add_for_references {
|
///
|
||||||
($ty:ident) => {
|
/// # Limitations
|
||||||
impl core::ops::Add<$ty> for &$ty {
|
///
|
||||||
type Output = $ty;
|
/// You must specify `$other_ty` and you may not use `Self`. So e.g. you need
|
||||||
|
/// to write `impl ops::Add<Amount> for Amount { ... }` when calling this macro.
|
||||||
fn add(self, rhs: $ty) -> Self::Output { *self + rhs }
|
///
|
||||||
|
/// Your where clause must include extra parenthesis, like `where (T: Copy)`.
|
||||||
|
macro_rules! impl_op_for_references {
|
||||||
|
($(
|
||||||
|
impl$(<$gen:ident>)? $($op_trait:ident)::+<$other_ty:ty> for $ty:ty
|
||||||
|
$(where ($($bounds:tt)*))?
|
||||||
|
{
|
||||||
|
type Output = $($main_output:ty)*;
|
||||||
|
fn $op:ident($($main_args:tt)*) -> Self::Output {
|
||||||
|
$($main_impl:tt)*
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)+) => {$(
|
||||||
|
impl$(<$gen>)? $($op_trait)::+<$other_ty> for $ty
|
||||||
|
$(where $($bounds)*)?
|
||||||
|
{
|
||||||
|
type Output = $($main_output)*;
|
||||||
|
fn $op($($main_args)*) -> Self::Output {
|
||||||
|
$($main_impl)*
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl core::ops::Add<&$ty> for $ty {
|
impl$(<$gen>)? $($op_trait)::+<$other_ty> for &$ty
|
||||||
type Output = $ty;
|
$(where $($bounds)*)?
|
||||||
|
{
|
||||||
fn add(self, rhs: &$ty) -> Self::Output { self + *rhs }
|
type Output = <$ty as $($op_trait)::+<$other_ty>>::Output;
|
||||||
|
fn $op(self, rhs: $other_ty) -> Self::Output {
|
||||||
|
(*self).$op(rhs)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> core::ops::Add<&'a $ty> for &$ty {
|
impl$(<$gen>)? $($op_trait)::+<&$other_ty> for $ty
|
||||||
type Output = $ty;
|
$(where $($bounds)*)?
|
||||||
|
{
|
||||||
fn add(self, rhs: &'a $ty) -> Self::Output { *self + *rhs }
|
type Output = <$ty as $($op_trait)::+<$other_ty>>::Output;
|
||||||
|
fn $op(self, rhs: &$other_ty) -> Self::Output {
|
||||||
|
self.$op(*rhs)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
|
||||||
|
impl<'a, $($gen)?> $($op_trait)::+<&'a $other_ty> for &$ty
|
||||||
|
$(where $($bounds)*)?
|
||||||
|
{
|
||||||
|
type Output = <$ty as $($op_trait)::+<$other_ty>>::Output;
|
||||||
|
fn $op(self, rhs: &$other_ty) -> Self::Output {
|
||||||
|
(*self).$op(*rhs)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)+};
|
||||||
}
|
}
|
||||||
pub(crate) use impl_add_for_references;
|
pub(crate) use impl_op_for_references;
|
||||||
|
|
||||||
/// Implements `ops::Add` for various amount references.
|
|
||||||
///
|
|
||||||
/// Requires `$ty` it implement `Add` e.g. 'impl Add<T> for T'. Adds impls of:
|
|
||||||
///
|
|
||||||
/// - Add<T> for &T
|
|
||||||
/// - Add<&T> for T
|
|
||||||
/// - Add<&T> for &T
|
|
||||||
macro_rules! impl_add_for_amount_references {
|
|
||||||
($ty:ident) => {
|
|
||||||
impl core::ops::Add<$ty> for &$ty {
|
|
||||||
type Output = NumOpResult<$ty>;
|
|
||||||
|
|
||||||
fn add(self, rhs: $ty) -> Self::Output { *self + rhs }
|
|
||||||
}
|
|
||||||
|
|
||||||
impl core::ops::Add<&$ty> for $ty {
|
|
||||||
type Output = NumOpResult<$ty>;
|
|
||||||
|
|
||||||
fn add(self, rhs: &$ty) -> Self::Output { self + *rhs }
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a> core::ops::Add<&'a $ty> for &$ty {
|
|
||||||
type Output = NumOpResult<$ty>;
|
|
||||||
|
|
||||||
fn add(self, rhs: &'a $ty) -> Self::Output { *self + *rhs }
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
pub(crate) use impl_add_for_amount_references;
|
|
||||||
|
|
||||||
/// Implement `ops::AddAssign` for `$ty` and `&$ty`.
|
/// Implement `ops::AddAssign` for `$ty` and `&$ty`.
|
||||||
macro_rules! impl_add_assign {
|
macro_rules! impl_add_assign {
|
||||||
|
@ -78,66 +83,6 @@ macro_rules! impl_add_assign {
|
||||||
}
|
}
|
||||||
pub(crate) use impl_add_assign;
|
pub(crate) use impl_add_assign;
|
||||||
|
|
||||||
/// Implement `ops::Sub` for various references.
|
|
||||||
///
|
|
||||||
/// Requires `$ty` it implement `Sub` e.g. 'impl Sub<T> for T'. Adds impls of:
|
|
||||||
///
|
|
||||||
/// - Sub<T> for &T
|
|
||||||
/// - Sub<&T> for T
|
|
||||||
/// - Sub<&T> for &T
|
|
||||||
macro_rules! impl_sub_for_references {
|
|
||||||
($ty:ident) => {
|
|
||||||
impl core::ops::Sub<$ty> for &$ty {
|
|
||||||
type Output = $ty;
|
|
||||||
|
|
||||||
fn sub(self, rhs: $ty) -> Self::Output { *self - rhs }
|
|
||||||
}
|
|
||||||
|
|
||||||
impl core::ops::Sub<&$ty> for $ty {
|
|
||||||
type Output = $ty;
|
|
||||||
|
|
||||||
fn sub(self, rhs: &$ty) -> Self::Output { self - *rhs }
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a> core::ops::Sub<&'a $ty> for &$ty {
|
|
||||||
type Output = $ty;
|
|
||||||
|
|
||||||
fn sub(self, rhs: &'a $ty) -> Self::Output { *self - *rhs }
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
pub(crate) use impl_sub_for_references;
|
|
||||||
|
|
||||||
/// Implement `ops::Sub` for various amount references.
|
|
||||||
///
|
|
||||||
/// Requires `$ty` it implement `Sub` e.g. 'impl Sub<T> for T'. Adds impls of:
|
|
||||||
///
|
|
||||||
/// - Sub<T> for &T
|
|
||||||
/// - Sub<&T> for T
|
|
||||||
/// - Sub<&T> for &T
|
|
||||||
macro_rules! impl_sub_for_amount_references {
|
|
||||||
($ty:ident) => {
|
|
||||||
impl core::ops::Sub<$ty> for &$ty {
|
|
||||||
type Output = NumOpResult<$ty>;
|
|
||||||
|
|
||||||
fn sub(self, rhs: $ty) -> Self::Output { *self - rhs }
|
|
||||||
}
|
|
||||||
|
|
||||||
impl core::ops::Sub<&$ty> for $ty {
|
|
||||||
type Output = NumOpResult<$ty>;
|
|
||||||
|
|
||||||
fn sub(self, rhs: &$ty) -> Self::Output { self - *rhs }
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a> core::ops::Sub<&'a $ty> for &$ty {
|
|
||||||
type Output = NumOpResult<$ty>;
|
|
||||||
|
|
||||||
fn sub(self, rhs: &'a $ty) -> Self::Output { *self - *rhs }
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
pub(crate) use impl_sub_for_amount_references;
|
|
||||||
|
|
||||||
/// Implement `ops::SubAssign` for `$ty` and `&$ty`.
|
/// Implement `ops::SubAssign` for `$ty` and `&$ty`.
|
||||||
macro_rules! impl_sub_assign {
|
macro_rules! impl_sub_assign {
|
||||||
($ty:ident) => {
|
($ty:ident) => {
|
||||||
|
|
|
@ -166,50 +166,46 @@ impl From<Weight> for u64 {
|
||||||
fn from(value: Weight) -> Self { value.to_wu() }
|
fn from(value: Weight) -> Self { value.to_wu() }
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ops::Add for Weight {
|
crate::internal_macros::impl_op_for_references! {
|
||||||
type Output = Weight;
|
impl ops::Add<Weight> for Weight {
|
||||||
|
type Output = Weight;
|
||||||
|
|
||||||
fn add(self, rhs: Weight) -> Self::Output { Weight(self.0 + rhs.0) }
|
fn add(self, rhs: Weight) -> Self::Output { Weight(self.0 + rhs.0) }
|
||||||
|
}
|
||||||
|
impl ops::Sub<Weight> for Weight {
|
||||||
|
type Output = Weight;
|
||||||
|
|
||||||
|
fn sub(self, rhs: Weight) -> Self::Output { Weight(self.0 - rhs.0) }
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ops::Mul<u64> for Weight {
|
||||||
|
type Output = Weight;
|
||||||
|
|
||||||
|
fn mul(self, rhs: u64) -> Self::Output { Weight(self.0 * rhs) }
|
||||||
|
}
|
||||||
|
impl ops::Mul<Weight> for u64 {
|
||||||
|
type Output = Weight;
|
||||||
|
|
||||||
|
fn mul(self, rhs: Weight) -> Self::Output { Weight(self * rhs.0) }
|
||||||
|
}
|
||||||
|
impl ops::Div<u64> for Weight {
|
||||||
|
type Output = Weight;
|
||||||
|
|
||||||
|
fn div(self, rhs: u64) -> Self::Output { Weight(self.0 / rhs) }
|
||||||
|
}
|
||||||
|
impl ops::Div<Weight> for Weight {
|
||||||
|
type Output = u64;
|
||||||
|
|
||||||
|
fn div(self, rhs: Weight) -> Self::Output { self.to_wu() / rhs.to_wu() }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
crate::internal_macros::impl_add_for_references!(Weight);
|
|
||||||
crate::internal_macros::impl_add_assign!(Weight);
|
crate::internal_macros::impl_add_assign!(Weight);
|
||||||
|
|
||||||
impl ops::Sub for Weight {
|
|
||||||
type Output = Weight;
|
|
||||||
|
|
||||||
fn sub(self, rhs: Weight) -> Self::Output { Weight(self.0 - rhs.0) }
|
|
||||||
}
|
|
||||||
crate::internal_macros::impl_sub_for_references!(Weight);
|
|
||||||
crate::internal_macros::impl_sub_assign!(Weight);
|
crate::internal_macros::impl_sub_assign!(Weight);
|
||||||
|
|
||||||
impl ops::Mul<u64> for Weight {
|
|
||||||
type Output = Weight;
|
|
||||||
|
|
||||||
fn mul(self, rhs: u64) -> Self::Output { Weight(self.0 * rhs) }
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ops::Mul<Weight> for u64 {
|
|
||||||
type Output = Weight;
|
|
||||||
|
|
||||||
fn mul(self, rhs: Weight) -> Self::Output { Weight(self * rhs.0) }
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ops::MulAssign<u64> for Weight {
|
impl ops::MulAssign<u64> for Weight {
|
||||||
fn mul_assign(&mut self, rhs: u64) { self.0 *= rhs }
|
fn mul_assign(&mut self, rhs: u64) { self.0 *= rhs }
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ops::Div<u64> for Weight {
|
|
||||||
type Output = Weight;
|
|
||||||
|
|
||||||
fn div(self, rhs: u64) -> Self::Output { Weight(self.0 / rhs) }
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ops::Div<Weight> for Weight {
|
|
||||||
type Output = u64;
|
|
||||||
|
|
||||||
fn div(self, rhs: Weight) -> Self::Output { self.to_wu() / rhs.to_wu() }
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ops::DivAssign<u64> for Weight {
|
impl ops::DivAssign<u64> for Weight {
|
||||||
fn div_assign(&mut self, rhs: u64) { self.0 /= rhs }
|
fn div_assign(&mut self, rhs: u64) { self.0 /= rhs }
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue