Skip to content

Commit 17d81bb

Browse files
authored
Merge pull request #7623 from drinkcat/parse-bigdecimal-smallfixes
uucore: format: Collection of small parser fixes
2 parents fb16585 + bdc8cd1 commit 17d81bb

File tree

5 files changed

+335
-102
lines changed

5 files changed

+335
-102
lines changed

src/uucore/src/lib/features/format/argument.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -105,9 +105,13 @@ fn extract_value<T: Default>(p: Result<T, ExtendedParserError<'_, T>>, input: &s
105105
},
106106
);
107107
match e {
108-
ExtendedParserError::Overflow => {
108+
ExtendedParserError::Overflow(v) => {
109109
show_error!("{}: Numerical result out of range", input.quote());
110-
Default::default()
110+
v
111+
}
112+
ExtendedParserError::Underflow(v) => {
113+
show_error!("{}: Numerical result out of range", input.quote());
114+
v
111115
}
112116
ExtendedParserError::NotNumeric => {
113117
show_error!("{}: expected a numeric value", input.quote());

src/uucore/src/lib/features/format/extendedbigdecimal.rs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
use std::cmp::Ordering;
2424
use std::fmt::Display;
2525
use std::ops::Add;
26+
use std::ops::Neg;
2627

2728
use bigdecimal::BigDecimal;
2829
use num_traits::FromPrimitive;
@@ -227,6 +228,27 @@ impl PartialOrd for ExtendedBigDecimal {
227228
}
228229
}
229230

231+
impl Neg for ExtendedBigDecimal {
232+
type Output = Self;
233+
234+
fn neg(self) -> Self::Output {
235+
match self {
236+
Self::BigDecimal(bd) => {
237+
if bd.is_zero() {
238+
Self::MinusZero
239+
} else {
240+
Self::BigDecimal(bd.neg())
241+
}
242+
}
243+
Self::MinusZero => Self::BigDecimal(BigDecimal::zero()),
244+
Self::Infinity => Self::MinusInfinity,
245+
Self::MinusInfinity => Self::Infinity,
246+
Self::Nan => Self::MinusNan,
247+
Self::MinusNan => Self::Nan,
248+
}
249+
}
250+
}
251+
230252
#[cfg(test)]
231253
mod tests {
232254

src/uucore/src/lib/features/format/num_format.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -80,10 +80,12 @@ pub struct SignedInt {
8080

8181
impl Formatter<i64> for SignedInt {
8282
fn fmt(&self, writer: impl Write, x: i64) -> std::io::Result<()> {
83+
// -i64::MIN is actually 1 larger than i64::MAX, so we need to cast to i128 first.
84+
let abs = (x as i128).abs();
8385
let s = if self.precision > 0 {
84-
format!("{:0>width$}", x.abs(), width = self.precision)
86+
format!("{:0>width$}", abs, width = self.precision)
8587
} else {
86-
x.abs().to_string()
88+
abs.to_string()
8789
};
8890

8991
let sign_indicator = get_sign_indicator(self.positive_sign, x.is_negative());
@@ -1046,6 +1048,8 @@ mod test {
10461048
let format = Format::<SignedInt, i64>::parse("%d").unwrap();
10471049
assert_eq!(fmt(&format, 123i64), "123");
10481050
assert_eq!(fmt(&format, -123i64), "-123");
1051+
assert_eq!(fmt(&format, i64::MAX), "9223372036854775807");
1052+
assert_eq!(fmt(&format, i64::MIN), "-9223372036854775808");
10491053

10501054
let format = Format::<SignedInt, i64>::parse("%i").unwrap();
10511055
assert_eq!(fmt(&format, 123i64), "123");

0 commit comments

Comments
 (0)