Add scalar coersion

This commit is contained in:
Yuheng Chen 2015-05-25 13:54:39 +08:00
parent b070a75ccb
commit fe07995ee4
2 changed files with 21 additions and 11 deletions

View file

@ -130,9 +130,20 @@ impl<T: Iterator<Item=char>> Parser<T> {
fn load_node(&mut self, first_ev: &Event) -> Result<Yaml, ScanError> { fn load_node(&mut self, first_ev: &Event) -> Result<Yaml, ScanError> {
match *first_ev { match *first_ev {
Event::Scalar(ref v, _) => { Event::Scalar(ref v, style) => {
// TODO scalar // TODO scalar
if style != TScalarStyle::Plain {
Ok(Yaml::String(v.clone())) Ok(Yaml::String(v.clone()))
} else {
match v.as_ref() {
"~" => Ok(Yaml::Null),
"true" => Ok(Yaml::Boolean(true)),
"false" => Ok(Yaml::Boolean(false)),
// try parsing as f64
_ if v.parse::<f64>().is_ok() => Ok(Yaml::Number(v.clone())),
_ => Ok(Yaml::String(v.clone()))
}
}
}, },
Event::SequenceStart => { Event::SequenceStart => {
self.load_sequence(first_ev) self.load_sequence(first_ev)
@ -140,6 +151,7 @@ impl<T: Iterator<Item=char>> Parser<T> {
Event::MappingStart => { Event::MappingStart => {
self.load_mapping(first_ev) self.load_mapping(first_ev)
}, },
// TODO more events
_ => { unreachable!(); } _ => { unreachable!(); }
} }
} }

View file

@ -5,9 +5,8 @@ use std::str::FromStr;
#[derive(Clone, PartialEq, PartialOrd, Debug, Eq, Ord)] #[derive(Clone, PartialEq, PartialOrd, Debug, Eq, Ord)]
pub enum Yaml { pub enum Yaml {
I64(i64), /// number types are stored as String
//U64(u64), Number(string::String),
//F64(f64),
String(string::String), String(string::String),
Boolean(bool), Boolean(bool),
Array(self::Array), Array(self::Array),
@ -66,7 +65,6 @@ pub fn $name(&self) -> Option<$t> {
); );
impl Yaml { impl Yaml {
define_as!(as_i64, i64, I64);
define_as!(as_bool, bool, Boolean); define_as!(as_bool, bool, Boolean);
define_as_ref!(as_str, &str, String); define_as_ref!(as_str, &str, String);
@ -87,10 +85,9 @@ impl Yaml {
} }
} }
pub fn parse<T: FromStr>(&self) -> Option<T> { pub fn as_number<T: FromStr>(&self) -> Option<T> {
// XXX(chenyh) precompile me
match *self { match *self {
Yaml::String(ref v) => { Yaml::Number(ref v) => {
v.parse::<T>().ok() v.parse::<T>().ok()
}, },
_ => None _ => None
@ -140,8 +137,9 @@ c: [1, 2]
"; ";
let mut parser = Parser::new(s.chars()); let mut parser = Parser::new(s.chars());
let out = parser.load().unwrap(); let out = parser.load().unwrap();
assert_eq!(out["a"].as_str().unwrap(), "1"); assert_eq!(out["a"].as_number::<i32>().unwrap(), 1);
assert_eq!(out["c"][1].parse::<i32>().unwrap(), 2); assert_eq!(out["b"].as_number::<f32>().unwrap(), 2.2f32);
assert_eq!(out["c"][1].as_number::<i32>().unwrap(), 2);
assert!(out["d"][0].is_badvalue()); assert!(out["d"][0].is_badvalue());
//assert_eq!(out.as_hash().unwrap()[&Yaml::String("a".to_string())].as_i64().unwrap(), 1i64); //assert_eq!(out.as_hash().unwrap()[&Yaml::String("a".to_string())].as_i64().unwrap(), 1i64);
} }