mirror of
https://github.com/RGBCube/uutils-coreutils
synced 2025-08-01 05:27:45 +00:00
uucore: format: num_parser: Fold special value parsing in main parsing function
This commit is contained in:
parent
20add88afc
commit
8bbec16115
1 changed files with 29 additions and 18 deletions
|
@ -155,32 +155,39 @@ impl ParsedNumber {
|
||||||
pub fn parse_f64(input: &str) -> Result<f64, ParseError<'_, f64>> {
|
pub fn parse_f64(input: &str) -> Result<f64, ParseError<'_, f64>> {
|
||||||
match Self::parse(input, false) {
|
match Self::parse(input, false) {
|
||||||
Ok(v) => Ok(v.into_f64()),
|
Ok(v) => Ok(v.into_f64()),
|
||||||
Err(ParseError::NotNumeric) => Self::parse_f64_special_values(input),
|
|
||||||
Err(e) => Err(e.map(|v, rest| ParseError::PartialMatch(v.into_f64(), rest))),
|
Err(e) => Err(e.map(|v, rest| ParseError::PartialMatch(v.into_f64(), rest))),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_f64_special_values(input: &str) -> Result<f64, ParseError<'_, f64>> {
|
fn parse_special_value(input: &str, negative: bool) -> Result<Self, ParseError<'_, Self>> {
|
||||||
let (sign, rest) = if let Some(input) = input.strip_prefix('-') {
|
let prefix = input
|
||||||
(-1.0, input)
|
|
||||||
} else {
|
|
||||||
(1.0, input)
|
|
||||||
};
|
|
||||||
let prefix = rest
|
|
||||||
.chars()
|
.chars()
|
||||||
.take(3)
|
.take(3)
|
||||||
.map(|c| c.to_ascii_lowercase())
|
.map(|c| c.to_ascii_lowercase())
|
||||||
.collect::<String>();
|
.collect::<String>();
|
||||||
let special = match prefix.as_str() {
|
let special = Self {
|
||||||
"inf" => f64::INFINITY,
|
number: match prefix.as_str() {
|
||||||
"nan" => f64::NAN,
|
"inf" => {
|
||||||
_ => return Err(ParseError::NotNumeric),
|
if negative {
|
||||||
|
ExtendedBigDecimal::MinusInfinity
|
||||||
|
} else {
|
||||||
|
ExtendedBigDecimal::Infinity
|
||||||
}
|
}
|
||||||
.copysign(sign);
|
}
|
||||||
if rest.len() == 3 {
|
"nan" => {
|
||||||
|
if negative {
|
||||||
|
ExtendedBigDecimal::MinusNan
|
||||||
|
} else {
|
||||||
|
ExtendedBigDecimal::Nan
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => return Err(ParseError::NotNumeric),
|
||||||
|
},
|
||||||
|
};
|
||||||
|
if input.len() == 3 {
|
||||||
Ok(special)
|
Ok(special)
|
||||||
} else {
|
} else {
|
||||||
Err(ParseError::PartialMatch(special, &rest[3..]))
|
Err(ParseError::PartialMatch(special, &input[3..]))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -251,9 +258,13 @@ impl ParsedNumber {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// If nothing has been parsed, declare the parsing unsuccessful
|
// If nothing has been parsed, check if this is a special value, or declare the parsing unsuccessful
|
||||||
if let Some((0, _)) = chars.peek() {
|
if let Some((0, _)) = chars.peek() {
|
||||||
|
if integral_only {
|
||||||
return Err(ParseError::NotNumeric);
|
return Err(ParseError::NotNumeric);
|
||||||
|
} else {
|
||||||
|
return Self::parse_special_value(unsigned, negative);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Might be nice to implement a ExtendedBigDecimal copysign or negation function to move away some of this logic...
|
// TODO: Might be nice to implement a ExtendedBigDecimal copysign or negation function to move away some of this logic...
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue