Handle inf/nan in delimited data (#2652)

This commit is contained in:
Chris Gillespie 2020-10-08 23:27:01 -07:00 committed by GitHub
parent 2b076369e0
commit 6817b472d0
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -202,13 +202,22 @@ impl UntaggedValue {
pub fn decimal_from_float(f: f64, span: Span) -> UntaggedValue {
let dec = BigDecimal::from_f64(f);
match dec {
Some(dec) => UntaggedValue::Primitive(Primitive::Decimal(dec)),
None => UntaggedValue::Error(ShellError::labeled_error(
"Can not convert f64 to big decimal",
"can not create decimal",
span,
)),
// BigDecimal doesn't have the concept of inf/NaN so handle manually
if f.is_sign_negative() && f.is_infinite() {
UntaggedValue::from("-inf")
} else if f.is_infinite() {
UntaggedValue::from("inf")
} else if f.is_nan() {
UntaggedValue::from("NaN")
} else {
match dec {
Some(dec) => UntaggedValue::Primitive(Primitive::Decimal(dec)),
None => UntaggedValue::Error(ShellError::labeled_error(
"Can not convert f64 to big decimal",
"can not create decimal",
span,
)),
}
}
}
@ -550,3 +559,28 @@ pub fn merge_descriptors(values: &[Value]) -> Vec<String> {
}
ret
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_decimal_from_float() {
assert_eq!(
UntaggedValue::from("inf"),
UntaggedValue::decimal_from_float(f64::INFINITY, Span::default())
);
assert_eq!(
UntaggedValue::from("-inf"),
UntaggedValue::decimal_from_float(f64::NEG_INFINITY, Span::default())
);
assert_eq!(
UntaggedValue::from("NaN"),
UntaggedValue::decimal_from_float(f64::NAN, Span::default())
);
assert_eq!(
UntaggedValue::from(5.5),
UntaggedValue::decimal_from_float(5.5, Span::default())
)
}
}