mirror of
https://github.com/RGBCube/uutils-coreutils
synced 2025-07-30 12:37:49 +00:00
uucore: format: num_parser: "infinity" string parsing
Not just "inf" is allowed, also "infinity".
This commit is contained in:
parent
5c06dd580b
commit
0cb37c83b9
1 changed files with 31 additions and 25 deletions
|
@ -5,7 +5,7 @@
|
||||||
|
|
||||||
//! Utilities for parsing numbers in various formats
|
//! Utilities for parsing numbers in various formats
|
||||||
|
|
||||||
// spell-checker:ignore powf copysign prec inity bigdecimal extendedbigdecimal biguint
|
// spell-checker:ignore powf copysign prec inity infinit bigdecimal extendedbigdecimal biguint
|
||||||
|
|
||||||
use bigdecimal::{
|
use bigdecimal::{
|
||||||
BigDecimal,
|
BigDecimal,
|
||||||
|
@ -181,33 +181,34 @@ fn parse_special_value(
|
||||||
input: &str,
|
input: &str,
|
||||||
negative: bool,
|
negative: bool,
|
||||||
) -> Result<ExtendedBigDecimal, ExtendedParserError<'_, ExtendedBigDecimal>> {
|
) -> Result<ExtendedBigDecimal, ExtendedParserError<'_, ExtendedBigDecimal>> {
|
||||||
let prefix = input
|
let input_lc = input.to_ascii_lowercase();
|
||||||
.chars()
|
|
||||||
.take(3)
|
// Array of ("String to match", return value when sign positive, when sign negative)
|
||||||
.map(|c| c.to_ascii_lowercase())
|
const MATCH_TABLE: &[(&str, ExtendedBigDecimal)] = &[
|
||||||
.collect::<String>();
|
("infinity", ExtendedBigDecimal::Infinity),
|
||||||
let special = match prefix.as_str() {
|
("inf", ExtendedBigDecimal::Infinity),
|
||||||
"inf" => {
|
("nan", ExtendedBigDecimal::Nan),
|
||||||
|
];
|
||||||
|
|
||||||
|
for (str, ebd) in MATCH_TABLE.iter() {
|
||||||
|
if input_lc.starts_with(str) {
|
||||||
|
let mut special = ebd.clone();
|
||||||
if negative {
|
if negative {
|
||||||
ExtendedBigDecimal::MinusInfinity
|
special = -special;
|
||||||
} else {
|
|
||||||
ExtendedBigDecimal::Infinity
|
|
||||||
}
|
}
|
||||||
}
|
let match_len = str.len();
|
||||||
"nan" => {
|
return if input.len() == match_len {
|
||||||
if negative {
|
Ok(special)
|
||||||
ExtendedBigDecimal::MinusNan
|
|
||||||
} else {
|
} else {
|
||||||
ExtendedBigDecimal::Nan
|
Err(ExtendedParserError::PartialMatch(
|
||||||
}
|
special,
|
||||||
|
&input[match_len..],
|
||||||
|
))
|
||||||
|
};
|
||||||
}
|
}
|
||||||
_ => return Err(ExtendedParserError::NotNumeric),
|
|
||||||
};
|
|
||||||
if input.len() == 3 {
|
|
||||||
Ok(special)
|
|
||||||
} else {
|
|
||||||
Err(ExtendedParserError::PartialMatch(special, &input[3..]))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Err(ExtendedParserError::NotNumeric)
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: As highlighted by clippy, this function _is_ high cognitive complexity, jumps
|
// TODO: As highlighted by clippy, this function _is_ high cognitive complexity, jumps
|
||||||
|
@ -467,6 +468,9 @@ mod tests {
|
||||||
assert_eq!(Ok(f64::INFINITY), f64::extended_parse("Inf"));
|
assert_eq!(Ok(f64::INFINITY), f64::extended_parse("Inf"));
|
||||||
assert_eq!(Ok(f64::INFINITY), f64::extended_parse("InF"));
|
assert_eq!(Ok(f64::INFINITY), f64::extended_parse("InF"));
|
||||||
assert_eq!(Ok(f64::INFINITY), f64::extended_parse("INF"));
|
assert_eq!(Ok(f64::INFINITY), f64::extended_parse("INF"));
|
||||||
|
assert_eq!(Ok(f64::INFINITY), f64::extended_parse("infinity"));
|
||||||
|
assert_eq!(Ok(f64::INFINITY), f64::extended_parse("+infiNIty"));
|
||||||
|
assert_eq!(Ok(f64::NEG_INFINITY), f64::extended_parse("-INfinity"));
|
||||||
assert!(f64::extended_parse("NaN").unwrap().is_nan());
|
assert!(f64::extended_parse("NaN").unwrap().is_nan());
|
||||||
assert!(f64::extended_parse("NaN").unwrap().is_sign_positive());
|
assert!(f64::extended_parse("NaN").unwrap().is_sign_positive());
|
||||||
assert!(f64::extended_parse("+NaN").unwrap().is_nan());
|
assert!(f64::extended_parse("+NaN").unwrap().is_nan());
|
||||||
|
@ -477,8 +481,10 @@ mod tests {
|
||||||
assert!(f64::extended_parse("nan").unwrap().is_sign_positive());
|
assert!(f64::extended_parse("nan").unwrap().is_sign_positive());
|
||||||
assert!(f64::extended_parse("NAN").unwrap().is_nan());
|
assert!(f64::extended_parse("NAN").unwrap().is_nan());
|
||||||
assert!(f64::extended_parse("NAN").unwrap().is_sign_positive());
|
assert!(f64::extended_parse("NAN").unwrap().is_sign_positive());
|
||||||
assert!(matches!(f64::extended_parse("-infinity"),
|
assert!(matches!(f64::extended_parse("-infinit"),
|
||||||
Err(ExtendedParserError::PartialMatch(f, "inity")) if f == f64::NEG_INFINITY));
|
Err(ExtendedParserError::PartialMatch(f, "init")) if f == f64::NEG_INFINITY));
|
||||||
|
assert!(matches!(f64::extended_parse("-infinity00"),
|
||||||
|
Err(ExtendedParserError::PartialMatch(f, "00")) if f == f64::NEG_INFINITY));
|
||||||
assert!(f64::extended_parse(&format!("{}", u64::MAX)).is_ok());
|
assert!(f64::extended_parse(&format!("{}", u64::MAX)).is_ok());
|
||||||
assert!(f64::extended_parse(&format!("{}", i64::MIN)).is_ok());
|
assert!(f64::extended_parse(&format!("{}", i64::MIN)).is_ok());
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue