Allow parsing sub-sat denoms with decimal points
Numbers with only zeros after decimal points are valid if they are also multiples of `10^precision` (e.g. 1000 for msats). These were artificially disallowed as "too precise" which was at least misleading. This change allows parsing such numbers.
This commit is contained in:
parent
b3d9a267ea
commit
f1a3dc6719
|
@ -199,7 +199,13 @@ impl std::error::Error for ParseAmountError {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn is_too_precise(s: &str, precision: usize) -> bool {
|
fn is_too_precise(s: &str, precision: usize) -> bool {
|
||||||
s.contains('.') || precision >= s.len() || s.chars().rev().take(precision).any(|d| d != '0')
|
match s.find('.') {
|
||||||
|
Some(pos) =>
|
||||||
|
s[(pos + 1)..].chars().any(|d| d != '0')
|
||||||
|
|| precision >= pos
|
||||||
|
|| s[..pos].chars().rev().take(precision).any(|d| d != '0'),
|
||||||
|
None => precision >= s.len() || s.chars().rev().take(precision).any(|d| d != '0'),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Parse decimal string in the given denomination into a satoshi value and a
|
/// Parse decimal string in the given denomination into a satoshi value and a
|
||||||
|
@ -227,7 +233,7 @@ fn parse_signed_to_satoshi(
|
||||||
// The difference in precision between native (satoshi)
|
// The difference in precision between native (satoshi)
|
||||||
// and desired denomination.
|
// and desired denomination.
|
||||||
let precision_diff = -denom.precision();
|
let precision_diff = -denom.precision();
|
||||||
if precision_diff < 0 {
|
if precision_diff <= 0 {
|
||||||
// If precision diff is negative, this means we are parsing
|
// If precision diff is negative, this means we are parsing
|
||||||
// into a less precise amount. That is not allowed unless
|
// into a less precise amount. That is not allowed unless
|
||||||
// there are no decimals and the last digits are zeroes as
|
// there are no decimals and the last digits are zeroes as
|
||||||
|
@ -239,7 +245,7 @@ fn parse_signed_to_satoshi(
|
||||||
_ => return Err(ParseAmountError::TooPrecise),
|
_ => return Err(ParseAmountError::TooPrecise),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
s = &s[0..s.len() - last_n];
|
s = &s[0..s.find('.').unwrap_or(s.len()) - last_n];
|
||||||
0
|
0
|
||||||
} else {
|
} else {
|
||||||
precision_diff
|
precision_diff
|
||||||
|
@ -267,6 +273,7 @@ fn parse_signed_to_satoshi(
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
'.' => match decimals {
|
'.' => match decimals {
|
||||||
|
None if max_decimals <= 0 => break,
|
||||||
None => decimals = Some(0),
|
None => decimals = Some(0),
|
||||||
// Double decimal dot.
|
// Double decimal dot.
|
||||||
_ => return Err(ParseAmountError::InvalidFormat),
|
_ => return Err(ParseAmountError::InvalidFormat),
|
||||||
|
|
Loading…
Reference in New Issue