units: extend op reference macro to handle generics and where clauses
This is a bit ugly and requires that we put our where-clauses in parentheses because the macro_rules parser sucks, but it allows us to move the blanket-impls on NumOpResult into the macro. This commit moves one instance and updates the macro; the next commits will change the rest.
This commit is contained in:
parent
ad9564895b
commit
21ac5aefe0
|
@ -246,6 +246,20 @@ crate::internal_macros::impl_op_for_references! {
|
||||||
|
|
||||||
fn rem(self, modulus: i64) -> Self::Output { self.checked_rem(modulus).valid_or_error() }
|
fn rem(self, modulus: i64) -> Self::Output { self.checked_rem(modulus).valid_or_error() }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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::Neg for SignedAmount {
|
impl ops::Neg for SignedAmount {
|
||||||
|
@ -254,59 +268,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>
|
impl<T> ops::Sub for NumOpResult<T>
|
||||||
where
|
where
|
||||||
T: ops::Sub<Output = NumOpResult<T>>,
|
T: ops::Sub<Output = NumOpResult<T>>,
|
||||||
|
|
|
@ -17,37 +17,49 @@
|
||||||
///
|
///
|
||||||
/// You must specify `$other_ty` and you may not use `Self`. So e.g. you need
|
/// 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.
|
/// to write `impl ops::Add<Amount> for Amount { ... }` when calling this macro.
|
||||||
|
///
|
||||||
|
/// Your where clause must include extra parenthesis, like `where (T: Copy)`.
|
||||||
macro_rules! impl_op_for_references {
|
macro_rules! impl_op_for_references {
|
||||||
($(
|
($(
|
||||||
impl $($op_trait:ident)::+<$other_ty:ty> for $ty:ty {
|
impl$(<$gen:ident>)? $($op_trait:ident)::+<$other_ty:ty> for $ty:ty
|
||||||
|
$(where ($($bounds:tt)*))?
|
||||||
|
{
|
||||||
type Output = $($main_output:ty)*;
|
type Output = $($main_output:ty)*;
|
||||||
fn $op:ident($($main_args:tt)*) -> Self::Output {
|
fn $op:ident($($main_args:tt)*) -> Self::Output {
|
||||||
$($main_impl:tt)*
|
$($main_impl:tt)*
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
)+) => {$(
|
)+) => {$(
|
||||||
impl $($op_trait)::+<$other_ty> for $ty {
|
impl$(<$gen>)? $($op_trait)::+<$other_ty> for $ty
|
||||||
|
$(where $($bounds)*)?
|
||||||
|
{
|
||||||
type Output = $($main_output)*;
|
type Output = $($main_output)*;
|
||||||
fn $op($($main_args)*) -> Self::Output {
|
fn $op($($main_args)*) -> Self::Output {
|
||||||
$($main_impl)*
|
$($main_impl)*
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl $($op_trait)::+<$other_ty> for &$ty {
|
impl$(<$gen>)? $($op_trait)::+<$other_ty> for &$ty
|
||||||
|
$(where $($bounds)*)?
|
||||||
|
{
|
||||||
type Output = <$ty as $($op_trait)::+<$other_ty>>::Output;
|
type Output = <$ty as $($op_trait)::+<$other_ty>>::Output;
|
||||||
fn $op(self, rhs: $other_ty) -> Self::Output {
|
fn $op(self, rhs: $other_ty) -> Self::Output {
|
||||||
(*self).$op(rhs)
|
(*self).$op(rhs)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl $($op_trait)::+<&$other_ty> for $ty {
|
impl$(<$gen>)? $($op_trait)::+<&$other_ty> for $ty
|
||||||
|
$(where $($bounds)*)?
|
||||||
|
{
|
||||||
type Output = <$ty as $($op_trait)::+<$other_ty>>::Output;
|
type Output = <$ty as $($op_trait)::+<$other_ty>>::Output;
|
||||||
fn $op(self, rhs: &$other_ty) -> Self::Output {
|
fn $op(self, rhs: &$other_ty) -> Self::Output {
|
||||||
self.$op(*rhs)
|
self.$op(*rhs)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> $($op_trait)::+<&'a $other_ty> for &$ty {
|
impl<'a, $($gen)?> $($op_trait)::+<&'a $other_ty> for &$ty
|
||||||
|
$(where $($bounds)*)?
|
||||||
|
{
|
||||||
type Output = <$ty as $($op_trait)::+<$other_ty>>::Output;
|
type Output = <$ty as $($op_trait)::+<$other_ty>>::Output;
|
||||||
fn $op(self, rhs: &$other_ty) -> Self::Output {
|
fn $op(self, rhs: &$other_ty) -> Self::Output {
|
||||||
(*self).$op(*rhs)
|
(*self).$op(*rhs)
|
||||||
|
|
Loading…
Reference in New Issue