Merge rust-bitcoin/rust-bitcoin#2462: feat: implement TryFrom trait to `SignedAmount` and `Amount`
251579f4ef
feat: implement TryFrom trait to SignedAmount and Amount (Sumit Kumar) Pull request description: Closes: #2245 Adds `TryFrom<SignedAmount> for Amount` and `TryFrom<Amount> for Amount` in units module ACKs for top commit: tcharding: ACK251579f4ef
Kixunil: ACK251579f4ef
apoelstra: ACK251579f4ef
Tree-SHA512: 3e58d7a891019ccd272417eadc977037167439e3385a7b47c060fe93eba9c47fc37cdc0ca5551174ef2d93b256b2804ad7c01f5f2470ef9e9b7b912877aed11c
This commit is contained in:
commit
8f7cc4d6b3
|
@ -865,9 +865,9 @@ impl Amount {
|
||||||
pub fn checked_rem(self, rhs: u64) -> Option<Amount> { self.0.checked_rem(rhs).map(Amount) }
|
pub fn checked_rem(self, rhs: u64) -> Option<Amount> { self.0.checked_rem(rhs).map(Amount) }
|
||||||
|
|
||||||
/// Convert to a signed amount.
|
/// Convert to a signed amount.
|
||||||
pub fn to_signed(self) -> Result<SignedAmount, ParseAmountError> {
|
pub fn to_signed(self) -> Result<SignedAmount, OutOfRangeError> {
|
||||||
if self.to_sat() > SignedAmount::MAX.to_sat() as u64 {
|
if self.to_sat() > SignedAmount::MAX.to_sat() as u64 {
|
||||||
Err(ParseAmountError::OutOfRange(OutOfRangeError::too_big(true)))
|
Err(OutOfRangeError::too_big(true))
|
||||||
} else {
|
} else {
|
||||||
Ok(SignedAmount::from_sat(self.to_sat() as i64))
|
Ok(SignedAmount::from_sat(self.to_sat() as i64))
|
||||||
}
|
}
|
||||||
|
@ -957,6 +957,14 @@ impl FromStr for Amount {
|
||||||
fn from_str(s: &str) -> Result<Self, Self::Err> { Amount::from_str_with_denomination(s) }
|
fn from_str(s: &str) -> Result<Self, Self::Err> { Amount::from_str_with_denomination(s) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl TryFrom<SignedAmount> for Amount {
|
||||||
|
type Error = OutOfRangeError;
|
||||||
|
|
||||||
|
fn try_from(value: SignedAmount) -> Result<Self, Self::Error> {
|
||||||
|
value.to_unsigned()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl core::iter::Sum for Amount {
|
impl core::iter::Sum for Amount {
|
||||||
fn sum<I: Iterator<Item = Self>>(iter: I) -> Self {
|
fn sum<I: Iterator<Item = Self>>(iter: I) -> Self {
|
||||||
let sats: u64 = iter.map(|amt| amt.0).sum();
|
let sats: u64 = iter.map(|amt| amt.0).sum();
|
||||||
|
@ -1340,6 +1348,14 @@ impl FromStr for SignedAmount {
|
||||||
fn from_str(s: &str) -> Result<Self, Self::Err> { SignedAmount::from_str_with_denomination(s) }
|
fn from_str(s: &str) -> Result<Self, Self::Err> { SignedAmount::from_str_with_denomination(s) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl TryFrom<Amount> for SignedAmount {
|
||||||
|
type Error = OutOfRangeError;
|
||||||
|
|
||||||
|
fn try_from(value: Amount) -> Result<Self, Self::Error> {
|
||||||
|
value.to_signed()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl core::iter::Sum for SignedAmount {
|
impl core::iter::Sum for SignedAmount {
|
||||||
fn sum<I: Iterator<Item = Self>>(iter: I) -> Self {
|
fn sum<I: Iterator<Item = Self>>(iter: I) -> Self {
|
||||||
let sats: i64 = iter.map(|amt| amt.0).sum();
|
let sats: i64 = iter.map(|amt| amt.0).sum();
|
||||||
|
@ -1710,7 +1726,7 @@ mod verification {
|
||||||
if n1 <= i64::MAX as u64 {
|
if n1 <= i64::MAX as u64 {
|
||||||
Ok(SignedAmount::from_sat(n1.try_into().unwrap()))
|
Ok(SignedAmount::from_sat(n1.try_into().unwrap()))
|
||||||
} else {
|
} else {
|
||||||
Err(ParseAmountError::OutOfRange(OutOfRangeError::too_big(true)))
|
Err(OutOfRangeError::too_big(true))
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -1841,6 +1857,40 @@ mod tests {
|
||||||
#[test]
|
#[test]
|
||||||
fn from_int_btc_panic() { Amount::from_int_btc(u64::MAX); }
|
fn from_int_btc_panic() { Amount::from_int_btc(u64::MAX); }
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_signed_amount_try_from_amount() {
|
||||||
|
let ua_positive = Amount::from_sat(123);
|
||||||
|
let sa_positive = SignedAmount::try_from(ua_positive).unwrap();
|
||||||
|
assert_eq!(sa_positive, SignedAmount(123));
|
||||||
|
|
||||||
|
let ua_max = Amount::MAX;
|
||||||
|
let result = SignedAmount::try_from(ua_max);
|
||||||
|
assert_eq!(
|
||||||
|
result,
|
||||||
|
Err(OutOfRangeError {
|
||||||
|
is_signed: true,
|
||||||
|
is_greater_than_max: true
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_amount_try_from_signed_amount() {
|
||||||
|
let sa_positive = SignedAmount(123);
|
||||||
|
let ua_positive = Amount::try_from(sa_positive).unwrap();
|
||||||
|
assert_eq!(ua_positive, Amount::from_sat(123));
|
||||||
|
|
||||||
|
let sa_negative = SignedAmount(-123);
|
||||||
|
let result = Amount::try_from(sa_negative);
|
||||||
|
assert_eq!(
|
||||||
|
result,
|
||||||
|
Err(OutOfRangeError {
|
||||||
|
is_signed: false,
|
||||||
|
is_greater_than_max: false
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn mul_div() {
|
fn mul_div() {
|
||||||
let sat = Amount::from_sat;
|
let sat = Amount::from_sat;
|
||||||
|
|
Loading…
Reference in New Issue