From 2c520ebeadec1f2aa96fcc08bf2538566c7d0796 Mon Sep 17 00:00:00 2001 From: Matthew Piziak Date: Sun, 7 Aug 2016 22:25:30 -0400 Subject: [PATCH 1/4] add `into_` counterparts for all `as_` methods fix #28 --- parser/src/yaml.rs | 78 +++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 77 insertions(+), 1 deletion(-) diff --git a/parser/src/yaml.rs b/parser/src/yaml.rs index 04a2fca..6cc1f1c 100644 --- a/parser/src/yaml.rs +++ b/parser/src/yaml.rs @@ -225,6 +225,17 @@ pub fn $name(&self) -> Option<$t> { ); ); +macro_rules! define_into ( + ($name:ident, $t:ty, $yt:ident) => ( +pub fn $name(self) -> Option<$t> { + match self { + Yaml::$yt(v) => Some(v), + _ => None + } +} + ); +); + impl Yaml { define_as!(as_bool, bool, Boolean); define_as!(as_i64, i64, Integer); @@ -233,6 +244,12 @@ impl Yaml { define_as_ref!(as_hash, &Hash, Hash); define_as_ref!(as_vec, &Array, Array); + define_into!(into_bool, bool, Boolean); + define_into!(into_i64, i64, Integer); + define_into!(into_string, String, String); + define_into!(into_hash, Hash, Hash); + define_into!(into_vec, Array, Array); + pub fn is_null(&self) -> bool { match *self { Yaml::Null => true, @@ -255,6 +272,15 @@ impl Yaml { _ => None } } + + pub fn into_f64(self) -> Option { + match self { + Yaml::Real(v) => { + v.parse::().ok() + }, + _ => None + } + } } #[cfg_attr(feature="clippy", allow(should_implement_trait))] @@ -490,6 +516,56 @@ a1: &DEFAULT assert!(YamlLoader::load_from_str("---This used to cause an infinite loop").is_ok()); assert_eq!(YamlLoader::load_from_str("----"), Ok(vec![Yaml::String(String::from("----"))])); assert_eq!(YamlLoader::load_from_str("--- #here goes a comment"), Ok(vec![Yaml::Null])); - assert_eq!(YamlLoader::load_from_str("---- #here goes a comment"), Ok(vec![Yaml::String(String::from("----"))])); + assert_eq!(YamlLoader::load_from_str("---- #here goes a comment"), Ok(vec![Yaml::String(String::from("----"))])); + } + + #[test] + fn test_plain_datatype_with_into_methods() { + let s = +" +- 'string' +- \"string\" +- string +- 123 +- -321 +- 1.23 +- -1e4 +- true +- false +- !!str 0 +- !!int 100 +- !!float 2 +- !!bool true +- !!bool false +- 0xFF +- 0o77 +- [ 0xF, 0xF ] +- +12345 +- [ true, false ] +"; + let out = YamlLoader::load_from_str(&s).unwrap(); + let doc = &out[0]; + + assert_eq!(doc[0].clone().into_string().unwrap(), "string"); + assert_eq!(doc[1].clone().into_string().unwrap(), "string"); + assert_eq!(doc[2].clone().into_string().unwrap(), "string"); + assert_eq!(doc[3].clone().into_i64().unwrap(), 123); + assert_eq!(doc[4].clone().into_i64().unwrap(), -321); + assert_eq!(doc[5].clone().into_f64().unwrap(), 1.23); + assert_eq!(doc[6].clone().into_f64().unwrap(), -1e4); + assert_eq!(doc[7].clone().into_bool().unwrap(), true); + assert_eq!(doc[8].clone().into_bool().unwrap(), false); + assert_eq!(doc[9].clone().into_string().unwrap(), "0"); + assert_eq!(doc[10].clone().into_i64().unwrap(), 100); + assert_eq!(doc[11].clone().into_f64().unwrap(), 2.0); + assert_eq!(doc[12].clone().into_bool().unwrap(), true); + assert_eq!(doc[13].clone().into_bool().unwrap(), false); + assert_eq!(doc[14].clone().into_i64().unwrap(), 255); + assert_eq!(doc[15].clone().into_i64().unwrap(), 63); + assert_eq!(doc[16][0].clone().into_i64().unwrap(), 15); + assert_eq!(doc[16][1].clone().into_i64().unwrap(), 15); + assert_eq!(doc[17].clone().into_i64().unwrap(), 12345); + assert!(doc[18][0].clone().into_bool().unwrap()); + assert!(!doc[18][1].clone().into_bool().unwrap()); } } From 3adfd050000bb3f8aaa1ebb4f3546a26b49df813 Mon Sep 17 00:00:00 2001 From: Matthew Piziak Date: Mon, 8 Aug 2016 17:31:36 -0400 Subject: [PATCH 2/4] implement IntoIterator for Yaml --- parser/src/yaml.rs | 68 +++++++++++++++++++++++++++++----------------- 1 file changed, 43 insertions(+), 25 deletions(-) diff --git a/parser/src/yaml.rs b/parser/src/yaml.rs index 6cc1f1c..96b4cc4 100644 --- a/parser/src/yaml.rs +++ b/parser/src/yaml.rs @@ -339,6 +339,30 @@ impl Index for Yaml { } } +impl IntoIterator for Yaml { + type Item = Yaml; + type IntoIter = YamlIter; + + fn into_iter(self) -> Self::IntoIter { + YamlIter {yaml: self, index: 0} + } +} + +pub struct YamlIter { + yaml: Yaml, + index: usize, +} + +impl Iterator for YamlIter { + type Item = Yaml; + + fn next(&mut self) -> Option { + let result = self.yaml[self.index].clone(); + self.index += 1; + Some(result) + } +} + #[cfg(test)] mod test { use yaml::*; @@ -539,33 +563,27 @@ a1: &DEFAULT - !!bool false - 0xFF - 0o77 -- [ 0xF, 0xF ] - +12345 -- [ true, false ] "; - let out = YamlLoader::load_from_str(&s).unwrap(); - let doc = &out[0]; + let mut out = YamlLoader::load_from_str(&s).unwrap().into_iter(); + let mut doc = out.next().unwrap().into_iter(); - assert_eq!(doc[0].clone().into_string().unwrap(), "string"); - assert_eq!(doc[1].clone().into_string().unwrap(), "string"); - assert_eq!(doc[2].clone().into_string().unwrap(), "string"); - assert_eq!(doc[3].clone().into_i64().unwrap(), 123); - assert_eq!(doc[4].clone().into_i64().unwrap(), -321); - assert_eq!(doc[5].clone().into_f64().unwrap(), 1.23); - assert_eq!(doc[6].clone().into_f64().unwrap(), -1e4); - assert_eq!(doc[7].clone().into_bool().unwrap(), true); - assert_eq!(doc[8].clone().into_bool().unwrap(), false); - assert_eq!(doc[9].clone().into_string().unwrap(), "0"); - assert_eq!(doc[10].clone().into_i64().unwrap(), 100); - assert_eq!(doc[11].clone().into_f64().unwrap(), 2.0); - assert_eq!(doc[12].clone().into_bool().unwrap(), true); - assert_eq!(doc[13].clone().into_bool().unwrap(), false); - assert_eq!(doc[14].clone().into_i64().unwrap(), 255); - assert_eq!(doc[15].clone().into_i64().unwrap(), 63); - assert_eq!(doc[16][0].clone().into_i64().unwrap(), 15); - assert_eq!(doc[16][1].clone().into_i64().unwrap(), 15); - assert_eq!(doc[17].clone().into_i64().unwrap(), 12345); - assert!(doc[18][0].clone().into_bool().unwrap()); - assert!(!doc[18][1].clone().into_bool().unwrap()); + assert_eq!(doc.next().unwrap().into_string().unwrap(), "string"); + assert_eq!(doc.next().unwrap().into_string().unwrap(), "string"); + assert_eq!(doc.next().unwrap().into_string().unwrap(), "string"); + assert_eq!(doc.next().unwrap().into_i64().unwrap(), 123); + assert_eq!(doc.next().unwrap().into_i64().unwrap(), -321); + assert_eq!(doc.next().unwrap().into_f64().unwrap(), 1.23); + assert_eq!(doc.next().unwrap().into_f64().unwrap(), -1e4); + assert_eq!(doc.next().unwrap().into_bool().unwrap(), true); + assert_eq!(doc.next().unwrap().into_bool().unwrap(), false); + assert_eq!(doc.next().unwrap().into_string().unwrap(), "0"); + assert_eq!(doc.next().unwrap().into_i64().unwrap(), 100); + assert_eq!(doc.next().unwrap().into_f64().unwrap(), 2.0); + assert_eq!(doc.next().unwrap().into_bool().unwrap(), true); + assert_eq!(doc.next().unwrap().into_bool().unwrap(), false); + 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); } } From b1b5526cf09c7710470e7db7d1a8bc8979afee42 Mon Sep 17 00:00:00 2001 From: Matthew Piziak Date: Mon, 8 Aug 2016 17:52:24 -0400 Subject: [PATCH 3/4] remove clone from `into_iter` --- parser/src/yaml.rs | 27 +++++++++++++-------------- 1 file changed, 13 insertions(+), 14 deletions(-) diff --git a/parser/src/yaml.rs b/parser/src/yaml.rs index 96b4cc4..e5af16f 100644 --- a/parser/src/yaml.rs +++ b/parser/src/yaml.rs @@ -234,7 +234,7 @@ pub fn $name(self) -> Option<$t> { } } ); -); +); impl Yaml { define_as!(as_bool, bool, Boolean); @@ -245,7 +245,7 @@ impl Yaml { define_as_ref!(as_vec, &Array, Array); define_into!(into_bool, bool, Boolean); - define_into!(into_i64, i64, Integer); + define_into!(into_i64, i64, Integer); define_into!(into_string, String, String); define_into!(into_hash, Hash, Hash); define_into!(into_vec, Array, Array); @@ -344,22 +344,21 @@ impl IntoIterator for Yaml { type IntoIter = YamlIter; fn into_iter(self) -> Self::IntoIter { - YamlIter {yaml: self, index: 0} + let mut yaml = self.into_vec().unwrap_or(vec![]); + yaml.reverse(); + YamlIter {yaml: yaml} } } pub struct YamlIter { - yaml: Yaml, - index: usize, + yaml: Vec, } impl Iterator for YamlIter { type Item = Yaml; fn next(&mut self) -> Option { - let result = self.yaml[self.index].clone(); - self.index += 1; - Some(result) + self.yaml.pop() } } @@ -540,7 +539,7 @@ a1: &DEFAULT assert!(YamlLoader::load_from_str("---This used to cause an infinite loop").is_ok()); assert_eq!(YamlLoader::load_from_str("----"), Ok(vec![Yaml::String(String::from("----"))])); assert_eq!(YamlLoader::load_from_str("--- #here goes a comment"), Ok(vec![Yaml::Null])); - assert_eq!(YamlLoader::load_from_str("---- #here goes a comment"), Ok(vec![Yaml::String(String::from("----"))])); + assert_eq!(YamlLoader::load_from_str("---- #here goes a comment"), Ok(vec![Yaml::String(String::from("----"))])); } #[test] @@ -561,13 +560,13 @@ a1: &DEFAULT - !!float 2 - !!bool true - !!bool false -- 0xFF +- 0xFF - 0o77 - +12345 "; - 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(); - + assert_eq!(doc.next().unwrap().into_string().unwrap(), "string"); assert_eq!(doc.next().unwrap().into_string().unwrap(), "string"); assert_eq!(doc.next().unwrap().into_string().unwrap(), "string"); @@ -583,7 +582,7 @@ a1: &DEFAULT assert_eq!(doc.next().unwrap().into_bool().unwrap(), true); assert_eq!(doc.next().unwrap().into_bool().unwrap(), false); 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_i64().unwrap(), 63); + assert_eq!(doc.next().unwrap().into_i64().unwrap(), 12345); } } From 79630e0cd1155ecb0c70e845d1fc813ee914aa67 Mon Sep 17 00:00:00 2001 From: Matthew Piziak Date: Mon, 8 Aug 2016 18:21:57 -0400 Subject: [PATCH 4/4] properly wrap Vec's IntoIter property --- parser/src/yaml.rs | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/parser/src/yaml.rs b/parser/src/yaml.rs index e5af16f..6ed730d 100644 --- a/parser/src/yaml.rs +++ b/parser/src/yaml.rs @@ -4,6 +4,7 @@ use std::string; use std::i64; use std::str::FromStr; use std::mem; +use std::vec; use parser::*; use scanner::{TScalarStyle, ScanError, TokenType}; @@ -344,21 +345,19 @@ impl IntoIterator for Yaml { type IntoIter = YamlIter; fn into_iter(self) -> Self::IntoIter { - let mut yaml = self.into_vec().unwrap_or(vec![]); - yaml.reverse(); - YamlIter {yaml: yaml} + YamlIter {yaml: self.into_vec().unwrap_or(vec![]).into_iter()} } } pub struct YamlIter { - yaml: Vec, + yaml: vec::IntoIter, } impl Iterator for YamlIter { type Item = Yaml; fn next(&mut self) -> Option { - self.yaml.pop() + self.yaml.next() } }