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() }
|
||||
}
|
||||
|
||||
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 {
|
||||
|
@ -254,59 +268,6 @@ impl ops::Neg for SignedAmount {
|
|||
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>>,
|
||||
|
|
|
@ -17,37 +17,49 @@
|
|||
///
|
||||
/// 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.
|
||||
///
|
||||
/// Your where clause must include extra parenthesis, like `where (T: Copy)`.
|
||||
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)*;
|
||||
fn $op:ident($($main_args:tt)*) -> Self::Output {
|
||||
$($main_impl:tt)*
|
||||
}
|
||||
}
|
||||
)+) => {$(
|
||||
impl $($op_trait)::+<$other_ty> for $ty {
|
||||
impl$(<$gen>)? $($op_trait)::+<$other_ty> for $ty
|
||||
$(where $($bounds)*)?
|
||||
{
|
||||
type Output = $($main_output)*;
|
||||
fn $op($($main_args)*) -> Self::Output {
|
||||
$($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;
|
||||
fn $op(self, rhs: $other_ty) -> Self::Output {
|
||||
(*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;
|
||||
fn $op(self, rhs: &$other_ty) -> Self::Output {
|
||||
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;
|
||||
fn $op(self, rhs: &$other_ty) -> Self::Output {
|
||||
(*self).$op(*rhs)
|
||||
|
|
Loading…
Reference in New Issue