From c3a9141330ed76eb8c8170f591f55b12d554e4fd Mon Sep 17 00:00:00 2001 From: Yuheng Chen Date: Sat, 13 May 2017 21:17:35 +0800 Subject: [PATCH] Add special f64 parsing Fix #51 --- parser/src/yaml.rs | 25 ++++++++++++++++++------- 1 file changed, 18 insertions(+), 7 deletions(-) diff --git a/parser/src/yaml.rs b/parser/src/yaml.rs index d67d6a2..99000df 100644 --- a/parser/src/yaml.rs +++ b/parser/src/yaml.rs @@ -2,6 +2,7 @@ use std::collections::BTreeMap; use std::ops::Index; use std::string; use std::i64; +use std::f64; use std::mem; use std::vec; use parser::*; @@ -226,6 +227,15 @@ pub fn $name(self) -> Option<$t> { ); ); +fn parse_f64(v: &str) -> Option { + match v { + ".inf" | ".Inf" | ".INF" | "+.inf" | "+.Inf" | "+.INF" => Some(f64::INFINITY), + "-.inf" | "-.Inf" | "-.INF" => Some(f64::NEG_INFINITY), + ".nan" | "NaN" | ".NAN" => Some(f64::NAN), + _ => v.parse::().ok() + } +} + impl Yaml { define_as!(as_bool, bool, Boolean); define_as!(as_i64, i64, Integer); @@ -256,18 +266,14 @@ impl Yaml { pub fn as_f64(&self) -> Option { match *self { - Yaml::Real(ref v) => { - v.parse::().ok() - }, + Yaml::Real(ref v) => parse_f64(v), _ => None } } pub fn into_f64(self) -> Option { match self { - Yaml::Real(v) => { - v.parse::().ok() - }, + Yaml::Real(ref v) => parse_f64(v), _ => None } } @@ -299,7 +305,7 @@ impl Yaml { "false" => Yaml::Boolean(false), _ if v.parse::().is_ok() => Yaml::Integer(v.parse::().unwrap()), // try parsing as f64 - _ if v.parse::().is_ok() => Yaml::Real(v.to_owned()), + _ if parse_f64(v).is_some() => Yaml::Real(v.to_owned()), _ => Yaml::String(v.to_owned()) } } @@ -356,6 +362,7 @@ impl Iterator for YamlIter { #[cfg(test)] mod test { use yaml::*; + use std::f64; #[test] fn test_coerce() { let s = "--- @@ -561,6 +568,8 @@ a1: &DEFAULT - 0xFF - 0o77 - +12345 +- -.INF +- .NAN "; let mut out = YamlLoader::load_from_str(&s).unwrap().into_iter(); let mut doc = out.next().unwrap().into_iter(); @@ -582,6 +591,8 @@ a1: &DEFAULT assert_eq!(doc.next().unwrap().into_i64().unwrap(), 255); assert_eq!(doc.next().unwrap().into_i64().unwrap(), 63); assert_eq!(doc.next().unwrap().into_i64().unwrap(), 12345); + assert_eq!(doc.next().unwrap().into_f64().unwrap(), f64::NEG_INFINITY); + assert!(doc.next().unwrap().into_f64().is_some()); } #[test]