diff --git a/units/src/amount.rs b/units/src/amount.rs index a8ac1f202..a305a5030 100644 --- a/units/src/amount.rs +++ b/units/src/amount.rs @@ -1157,7 +1157,22 @@ impl ops::DivAssign for Amount { impl FromStr for Amount { type Err = ParseError; - fn from_str(s: &str) -> Result { Amount::from_str_with_denomination(s) } + fn from_str(s: &str) -> Result { + let result = Amount::from_str_with_denomination(s); + + match result { + Err(ParseError::MissingDenomination(_)) => { + let d = Amount::from_str_in(s, Denomination::Satoshi); + + if d == Ok(Amount::ZERO) { + Ok(Amount::ZERO) + } else { + result + } + }, + _ => result + } + } } impl TryFrom for Amount { @@ -1580,7 +1595,22 @@ impl ops::Neg for SignedAmount { impl FromStr for SignedAmount { type Err = ParseError; - fn from_str(s: &str) -> Result { SignedAmount::from_str_with_denomination(s) } + fn from_str(s: &str) -> Result { + let result = SignedAmount::from_str_with_denomination(s); + + match result { + Err(ParseError::MissingDenomination(_)) => { + let d = SignedAmount::from_str_in(s, Denomination::Satoshi); + + if d == Ok(SignedAmount::ZERO) { + Ok(SignedAmount::ZERO) + } else { + result + } + }, + _ => result + } + } } impl TryFrom for SignedAmount { @@ -2079,6 +2109,25 @@ mod tests { } } + #[test] + fn from_str_zero_without_denomination() { + let _a = Amount::from_str("0").unwrap(); + let _a = Amount::from_str("0.0").unwrap(); + let _a = Amount::from_str("00.0").unwrap(); + + assert!(Amount::from_str("-0").is_err()); + assert!(Amount::from_str("-0.0").is_err()); + assert!(Amount::from_str("-00.0").is_err()); + + let _a = SignedAmount::from_str("-0").unwrap(); + let _a = SignedAmount::from_str("-0.0").unwrap(); + let _a = SignedAmount::from_str("-00.0").unwrap(); + + let _a = SignedAmount::from_str("0").unwrap(); + let _a = SignedAmount::from_str("0.0").unwrap(); + let _a = SignedAmount::from_str("00.0").unwrap(); + } + #[test] fn from_int_btc() { let amt = Amount::from_int_btc(2);