Merge branch 'master' of https://github.com/chyh1990/yaml-rust into chyh1990

This commit is contained in:
Charlie Ozinga 2017-05-23 11:51:19 -06:00
commit 7cc29540f2
2 changed files with 53 additions and 14 deletions

View file

@ -1294,12 +1294,12 @@ impl<T: Iterator<Item=char>> Scanner<T> {
} }
self.lookahead(2); self.lookahead(2);
} }
self.lookahead(1);
match self.ch() { match self.ch() {
'\'' if single => { break; }, '\'' if single => { break; },
'"' if !single => { break; }, '"' if !single => { break; },
_ => {} _ => {}
} }
self.lookahead(1);
// Consume blank characters. // Consume blank characters.
while is_blank(self.ch()) || is_break(self.ch()) { while is_blank(self.ch()) || is_break(self.ch()) {

View file

@ -2,6 +2,7 @@ use std::collections::BTreeMap;
use std::ops::Index; use std::ops::Index;
use std::string; use std::string;
use std::i64; use std::i64;
use std::f64;
use std::mem; use std::mem;
use std::vec; use std::vec;
use parser::*; use parser::*;
@ -54,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
@ -115,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" => {
@ -256,18 +268,14 @@ impl Yaml {
pub fn as_f64(&self) -> Option<f64> { pub fn as_f64(&self) -> Option<f64> {
match *self { match *self {
Yaml::Real(ref v) => { Yaml::Real(ref v) => parse_f64(v),
v.parse::<f64>().ok()
},
_ => None _ => None
} }
} }
pub fn into_f64(self) -> Option<f64> { pub fn into_f64(self) -> Option<f64> {
match self { match self {
Yaml::Real(v) => { Yaml::Real(ref v) => parse_f64(v),
v.parse::<f64>().ok()
},
_ => None _ => None
} }
} }
@ -299,7 +307,7 @@ impl Yaml {
"false" => Yaml::Boolean(false), "false" => Yaml::Boolean(false),
_ if v.parse::<i64>().is_ok() => Yaml::Integer(v.parse::<i64>().unwrap()), _ if v.parse::<i64>().is_ok() => Yaml::Integer(v.parse::<i64>().unwrap()),
// try parsing as f64 // try parsing as f64
_ if v.parse::<f64>().is_ok() => Yaml::Real(v.to_owned()), _ if parse_f64(v).is_some() => Yaml::Real(v.to_owned()),
_ => Yaml::String(v.to_owned()) _ => Yaml::String(v.to_owned())
} }
} }
@ -322,9 +330,13 @@ impl Index<usize> for Yaml {
type Output = Yaml; type Output = Yaml;
fn index(&self, idx: usize) -> &Yaml { fn index(&self, idx: usize) -> &Yaml {
match self.as_vec() { if let Some(v) = self.as_vec() {
Some(v) => v.get(idx).unwrap_or(&BAD_VALUE), v.get(idx).unwrap_or(&BAD_VALUE)
None => &BAD_VALUE } else if let Some(v) = self.as_hash() {
let key = Yaml::Integer(idx as i64);
v.get(&key).unwrap_or(&BAD_VALUE)
} else {
&BAD_VALUE
} }
} }
} }
@ -356,6 +368,7 @@ impl Iterator for YamlIter {
#[cfg(test)] #[cfg(test)]
mod test { mod test {
use yaml::*; use yaml::*;
use std::f64;
#[test] #[test]
fn test_coerce() { fn test_coerce() {
let s = "--- let s = "---
@ -525,6 +538,13 @@ a1: &DEFAULT
assert!(YamlLoader::load_from_str(&s).is_err()); assert!(YamlLoader::load_from_str(&s).is_err());
} }
#[test]
fn test_issue_65() {
// See: https://github.com/chyh1990/yaml-rust/issues/65
let b = "\n\"ll\\\"ll\\\r\n\"ll\\\"ll\\\r\r\r\rU\r\r\rU";
assert!(YamlLoader::load_from_str(&b).is_err());
}
#[test] #[test]
fn test_bad_docstart() { fn test_bad_docstart() {
assert!(YamlLoader::load_from_str("---This used to cause an infinite loop").is_ok()); assert!(YamlLoader::load_from_str("---This used to cause an infinite loop").is_ok());
@ -554,6 +574,9 @@ a1: &DEFAULT
- 0xFF - 0xFF
- 0o77 - 0o77
- +12345 - +12345
- -.INF
- .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();
@ -575,6 +598,9 @@ a1: &DEFAULT
assert_eq!(doc.next().unwrap().into_i64().unwrap(), 255); 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(), 63);
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!(doc.next().unwrap().into_f64().is_some());
assert_eq!(doc.next().unwrap().into_f64().unwrap(), f64::INFINITY);
} }
#[test] #[test]
@ -592,4 +618,17 @@ c: ~
assert_eq!(Some((Yaml::String("c".to_owned()), Yaml::Null)), iter.next()); assert_eq!(Some((Yaml::String("c".to_owned()), Yaml::Null)), iter.next());
assert_eq!(None, iter.next()); assert_eq!(None, iter.next());
} }
#[test]
fn test_integer_key() {
let s = "
0:
important: true
1:
important: false
";
let out = YamlLoader::load_from_str(&s).unwrap();
let first = out.into_iter().next().unwrap();
assert_eq!(first[0]["important"].as_bool().unwrap(), true);
}
} }