pub fn non_finite_float_text(f: f64) -> Option<&'static str> {
(!f.is_finite()).then(|| non_finite_text(f))
}
pub fn float_to_json(f: f64) -> serde_json::Value {
match serde_json::Number::from_f64(f) {
Some(n) => serde_json::Value::Number(n),
None => serde_json::Value::String(non_finite_text(f).to_owned()),
}
}
fn non_finite_text(f: f64) -> &'static str {
if f.is_nan() {
"NaN"
} else if f > 0.0 {
"Infinity"
} else {
"-Infinity"
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn non_finite_floats_render_postgres_text() {
assert_eq!(non_finite_float_text(f64::NAN), Some("NaN"));
assert_eq!(non_finite_float_text(f64::INFINITY), Some("Infinity"));
assert_eq!(non_finite_float_text(f64::NEG_INFINITY), Some("-Infinity"));
assert_eq!(non_finite_float_text(1.5), None);
assert_eq!(non_finite_float_text(f64::MAX), None);
}
#[test]
fn non_finite_floats_are_json_strings() {
assert_eq!(float_to_json(f64::NAN), serde_json::json!("NaN"));
assert_eq!(float_to_json(f64::INFINITY), serde_json::json!("Infinity"));
assert_eq!(
float_to_json(f64::NEG_INFINITY),
serde_json::json!("-Infinity")
);
assert_eq!(float_to_json(2.5), serde_json::json!(2.5));
}
}