From 6817b472d0c6d34abd87325514dc9389594e1d64 Mon Sep 17 00:00:00 2001 From: Chris Gillespie <6572184+gillespiecd@users.noreply.github.com> Date: Thu, 8 Oct 2020 23:27:01 -0700 Subject: [PATCH] Handle inf/nan in delimited data (#2652) --- crates/nu-protocol/src/value.rs | 48 ++++++++++++++++++++++++++++----- 1 file changed, 41 insertions(+), 7 deletions(-) diff --git a/crates/nu-protocol/src/value.rs b/crates/nu-protocol/src/value.rs index 28fcdf1b0a..6b45250a00 100644 --- a/crates/nu-protocol/src/value.rs +++ b/crates/nu-protocol/src/value.rs @@ -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 { } 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()) + ) + } +}