Parse special f64 in tag

This commit is contained in:
Yuheng Chen 2017-05-13 21:22:19 +08:00
parent f43b50bbce
commit 6ba376563b

View file

@ -55,6 +55,17 @@ pub enum Yaml {
pub type Array = Vec<Yaml>; pub type Array = Vec<Yaml>;
pub type Hash = LinkedHashMap<Yaml, Yaml>; pub type Hash = LinkedHashMap<Yaml, Yaml>;
// parse f64 as Core schema
// See: https://github.com/chyh1990/yaml-rust/issues/51
fn parse_f64(v: &str) -> Option<f64> {
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::<f64>().ok()
}
}
pub struct YamlLoader { pub struct YamlLoader {
docs: Vec<Yaml>, docs: Vec<Yaml>,
// states // states
@ -116,9 +127,9 @@ impl MarkedEventReceiver for YamlLoader {
} }
}, },
"float" => { "float" => {
match v.parse::<f64>() { match parse_f64(v) {
Err(_) => Yaml::BadValue, Some(_) => Yaml::Real(v.clone()),
Ok(_) => Yaml::Real(v.clone()) None => Yaml::BadValue,
} }
}, },
"null" => { "null" => {
@ -227,15 +238,6 @@ pub fn $name(self) -> Option<$t> {
); );
); );
fn parse_f64(v: &str) -> Option<f64> {
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::<f64>().ok()
}
}
impl Yaml { impl Yaml {
define_as!(as_bool, bool, Boolean); define_as!(as_bool, bool, Boolean);
define_as!(as_i64, i64, Integer); define_as!(as_i64, i64, Integer);
@ -570,6 +572,7 @@ a1: &DEFAULT
- +12345 - +12345
- -.INF - -.INF
- .NAN - .NAN
- !!float .INF
"; ";
let mut out = YamlLoader::load_from_str(&s).unwrap().into_iter(); let mut out = YamlLoader::load_from_str(&s).unwrap().into_iter();
let mut doc = out.next().unwrap().into_iter(); let mut doc = out.next().unwrap().into_iter();
@ -593,6 +596,7 @@ a1: &DEFAULT
assert_eq!(doc.next().unwrap().into_i64().unwrap(), 12345); assert_eq!(doc.next().unwrap().into_i64().unwrap(), 12345);
assert_eq!(doc.next().unwrap().into_f64().unwrap(), f64::NEG_INFINITY); assert_eq!(doc.next().unwrap().into_f64().unwrap(), f64::NEG_INFINITY);
assert!(doc.next().unwrap().into_f64().is_some()); assert!(doc.next().unwrap().into_f64().is_some());
assert_eq!(doc.next().unwrap().into_f64().unwrap(), f64::INFINITY);
} }
#[test] #[test]