Update to master

- features
- macro reform
- String/Show split in formatter
- staging
This commit is contained in:
Valerii Hiora 2015-01-07 18:58:50 +02:00
parent 6195861f53
commit 1dfb94afba
5 changed files with 100 additions and 79 deletions

View file

@ -15,7 +15,7 @@
//! "#; //! "#;
//! //!
//! let value = toml::Parser::new(toml).parse().unwrap(); //! let value = toml::Parser::new(toml).parse().unwrap();
//! println!("{}", value); //! println!("{:?}", value);
//! ``` //! ```
//! //!
//! # Conversions //! # Conversions
@ -36,9 +36,9 @@
//! [2]: https://github.com/BurntSushi/toml-test //! [2]: https://github.com/BurntSushi/toml-test
//! //!
#![feature(macro_rules)]
#![feature(associated_types)]
#![deny(missing_docs)] #![deny(missing_docs)]
#![allow(staged_experimental)]
#![allow(staged_unstable)]
#![cfg_attr(test, deny(warnings))] #![cfg_attr(test, deny(warnings))]
extern crate "rustc-serialize" as rustc_serialize; extern crate "rustc-serialize" as rustc_serialize;
@ -63,7 +63,7 @@ mod show;
mod serialization; mod serialization;
#[cfg(test)]mod test; #[cfg(test)]mod test;
/// Representation of a TOML value. /// Representation of a TOML value.
#[derive(PartialEq, Clone)] #[derive(PartialEq, Clone, Show)]
#[allow(missing_docs)] #[allow(missing_docs)]
pub enum Value { pub enum Value {
String(string::String), String(string::String),
@ -159,6 +159,7 @@ impl Value {
/// Note: arrays have zero-based indexes. /// Note: arrays have zero-based indexes.
/// ///
/// ``` /// ```
/// # #![allow(staged_unstable)]
/// let toml = r#" /// let toml = r#"
/// [test] /// [test]
/// foo = "bar" /// foo = "bar"

View file

@ -52,9 +52,9 @@ impl<'a> Parser<'a> {
/// ///
/// let mut parser = toml::Parser::new(toml); /// let mut parser = toml::Parser::new(toml);
/// match parser.parse() { /// match parser.parse() {
/// Some(value) => println!("found toml: {}", value), /// Some(value) => println!("found toml: {:?}", value),
/// None => { /// None => {
/// println!("parse errors: {}", parser.errors); /// println!("parse errors: {:?}", parser.errors);
/// } /// }
/// } /// }
/// ``` /// ```
@ -651,7 +651,7 @@ impl<'a> Parser<'a> {
} }
Array(ref mut array) => { Array(ref mut array) => {
match array.as_mut_slice().last_mut() { match array.as_mut_slice().last_mut() {
Some(&Table(ref mut table)) => cur = table, Some(&mut Table(ref mut table)) => cur = table,
_ => { _ => {
self.errors.push(ParserError { self.errors.push(ParserError {
lo: key_lo, lo: key_lo,
@ -699,7 +699,7 @@ impl<'a> Parser<'a> {
added = true; added = true;
} }
match into.get_mut(&key) { match into.get_mut(&key) {
Some(&Table(ref mut table)) => { Some(&mut Table(ref mut table)) => {
let any_tables = table.values().any(|v| v.as_table().is_some()); let any_tables = table.values().any(|v| v.as_table().is_some());
if !any_tables && !added { if !any_tables && !added {
self.errors.push(ParserError { self.errors.push(ParserError {

View file

@ -24,6 +24,8 @@ use self::DecodeErrorKind::{ExpectedMapElement, NoEnumVariants, NilTooLong};
/// ///
/// ``` /// ```
/// # #![feature(old_orphan_check)] /// # #![feature(old_orphan_check)]
/// # #![allow(staged_unstable)]
/// # #![allow(staged_experimental)]
/// extern crate "rustc-serialize" as rustc_serialize; /// extern crate "rustc-serialize" as rustc_serialize;
/// extern crate toml; /// extern crate toml;
/// ///
@ -108,7 +110,7 @@ pub enum DecodeErrorKind {
NilTooLong NilTooLong
} }
#[derive(PartialEq, Show)] #[derive(PartialEq)]
enum EncoderState { enum EncoderState {
Start, Start,
NextKey(String), NextKey(String),
@ -793,7 +795,7 @@ impl StdError for DecodeError {
NilTooLong => "nonzero length string representing nil", NilTooLong => "nonzero length string representing nil",
} }
} }
fn detail(&self) -> Option<String> { Some(self.to_string()) } fn detail(&self) -> Option<String> { Some(format!("{:?}", self)) }
} }
impl fmt::Show for Error { impl fmt::Show for Error {
@ -811,7 +813,7 @@ impl fmt::Show for Error {
impl StdError for Error { impl StdError for Error {
fn description(&self) -> &str { "TOML encoding error" } fn description(&self) -> &str { "TOML encoding error" }
fn detail(&self) -> Option<String> { Some(self.to_string()) } fn detail(&self) -> Option<String> { Some(format!("{:?}", self)) }
} }
#[cfg(test)] #[cfg(test)]
@ -834,7 +836,7 @@ mod tests {
Decodable::decode(&mut d).unwrap() Decodable::decode(&mut d).unwrap()
}) ); }) );
macro_rules! map( ($($k:ident: $v:expr),*) => ({ macro_rules! map( ($($k:ident, $v:expr),*) => ({
let mut _m = BTreeMap::new(); let mut _m = BTreeMap::new();
$(_m.insert(stringify!($k).to_string(), $v);)* $(_m.insert(stringify!($k).to_string(), $v);)*
_m _m
@ -846,7 +848,7 @@ mod tests {
struct Foo { a: int } struct Foo { a: int }
let v = Foo { a: 2 }; let v = Foo { a: 2 };
assert_eq!(encode!(v), map! { a: Integer(2) }); assert_eq!(encode!(v), map! { a, Integer(2) });
assert_eq!(v, decode!(Table(encode!(v)))); assert_eq!(v, decode!(Table(encode!(v))));
} }
@ -856,7 +858,7 @@ mod tests {
struct Foo { a_b: int } struct Foo { a_b: int }
let v = Foo { a_b: 2 }; let v = Foo { a_b: 2 };
assert_eq!(encode!(v), map! { a_b: Integer(2) }); assert_eq!(encode!(v), map! { a_b, Integer(2) });
assert_eq!(v, decode!(Table(encode!(v)))); assert_eq!(v, decode!(Table(encode!(v))));
let mut m = BTreeMap::new(); let mut m = BTreeMap::new();
@ -874,9 +876,9 @@ mod tests {
let v = Foo { a: 2, b: Bar { a: "test".to_string() } }; let v = Foo { a: 2, b: Bar { a: "test".to_string() } };
assert_eq!(encode!(v), assert_eq!(encode!(v),
map! { map! {
a: Integer(2), a, Integer(2),
b: Table(map! { b, Table(map! {
a: Value::String("test".to_string()) a, Value::String("test".to_string())
}) })
}); });
assert_eq!(v, decode!(Table(encode!(v)))); assert_eq!(v, decode!(Table(encode!(v))));
@ -916,7 +918,7 @@ mod tests {
let v = Foo { a: vec![1, 2, 3, 4] }; let v = Foo { a: vec![1, 2, 3, 4] };
assert_eq!(encode!(v), assert_eq!(encode!(v),
map! { map! {
a: Array(vec![ a, Array(vec![
Integer(1), Integer(1),
Integer(2), Integer(2),
Integer(3), Integer(3),
@ -934,7 +936,7 @@ mod tests {
let v = Foo { a: (1, 2, 3, 4) }; let v = Foo { a: (1, 2, 3, 4) };
assert_eq!(encode!(v), assert_eq!(encode!(v),
map! { map! {
a: Array(vec![ a, Array(vec![
Integer(1), Integer(1),
Integer(2), Integer(2),
Integer(3), Integer(3),
@ -958,23 +960,23 @@ mod tests {
} }
let v = Foo { let v = Foo {
a: Some(box Foo { a: Some(Box::new(Foo {
a: None, a: None,
b: Bar { a: "foo".to_string(), b: 4.5 }, b: Bar { a: "foo".to_string(), b: 4.5 },
}), })),
b: Bar { a: "bar".to_string(), b: 1.0 }, b: Bar { a: "bar".to_string(), b: 1.0 },
}; };
assert_eq!(encode!(v), assert_eq!(encode!(v),
map! { map! {
a: Table(map! { a, Table(map! {
b: Table(map! { b, Table(map! {
a: Value::String("foo".to_string()), a, Value::String("foo".to_string()),
b: Float(4.5) b, Float(4.5)
}) })
}), }),
b: Table(map! { b, Table(map! {
a: Value::String("bar".to_string()), a, Value::String("bar".to_string()),
b: Float(1.0) b, Float(1.0)
}) })
}); });
assert_eq!(v, decode!(Table(encode!(v)))); assert_eq!(v, decode!(Table(encode!(v))));
@ -1003,11 +1005,11 @@ mod tests {
}; };
assert_eq!(encode!(v), assert_eq!(encode!(v),
map! { map! {
map: Table(map! { map, Table(map! {
foo: Integer(10), foo, Integer(10),
bar: Integer(4) bar, Integer(4)
}), }),
set: Array(vec![Value::String("a".to_string())]) set, Array(vec![Value::String("a".to_string())])
} }
); );
assert_eq!(v, decode!(Table(encode!(v)))); assert_eq!(v, decode!(Table(encode!(v))));
@ -1022,9 +1024,9 @@ mod tests {
assert_eq!( assert_eq!(
encode!(v), encode!(v),
map! { map! {
_field0: Integer(1), _field0, Integer(1),
_field1: Value::String("foo".to_string()), _field1, Value::String("foo".to_string()),
_field2: Float(4.5) _field2, Float(4.5)
} }
); );
assert_eq!(v, decode!(Table(encode!(v)))); assert_eq!(v, decode!(Table(encode!(v))));
@ -1041,9 +1043,9 @@ mod tests {
assert_eq!( assert_eq!(
encode!(v), encode!(v),
map! { map! {
a: Array(vec![ a, Array(vec![
Table(map!{ a: Integer(1) }), Table(map!{ a, Integer(1) }),
Table(map!{ a: Integer(2) }), Table(map!{ a, Integer(2) }),
]) ])
} }
); );
@ -1056,13 +1058,13 @@ mod tests {
struct Foo { bar: int } struct Foo { bar: int }
let mut d = Decoder::new(Table(map! { let mut d = Decoder::new(Table(map! {
bar: Float(1.0) bar, Float(1.0)
})); }));
let a: Result<Foo, DecodeError> = Decodable::decode(&mut d); let a: Result<Foo, DecodeError> = Decodable::decode(&mut d);
match a { match a {
Ok(..) => panic!("should not have decoded"), Ok(..) => panic!("should not have decoded"),
Err(e) => { Err(e) => {
assert_eq!(e.to_string().as_slice(), assert_eq!(format!("{:?}", e).as_slice(),
"expected a value of type `integer`, but \ "expected a value of type `integer`, but \
found a value of type `float` for the key `bar`"); found a value of type `float` for the key `bar`");
} }
@ -1080,7 +1082,7 @@ mod tests {
match a { match a {
Ok(..) => panic!("should not have decoded"), Ok(..) => panic!("should not have decoded"),
Err(e) => { Err(e) => {
assert_eq!(e.to_string().as_slice(), assert_eq!(format!("{:?}", e).as_slice(),
"expected a value of type `integer` for the key `bar`"); "expected a value of type `integer` for the key `bar`");
} }
} }
@ -1104,21 +1106,21 @@ mod tests {
let v = Foo { a: E::Bar(10) }; let v = Foo { a: E::Bar(10) };
assert_eq!( assert_eq!(
encode!(v), encode!(v),
map! { a: Integer(10) } map! { a, Integer(10) }
); );
assert_eq!(v, decode!(Table(encode!(v)))); assert_eq!(v, decode!(Table(encode!(v))));
let v = Foo { a: E::Baz(10.2) }; let v = Foo { a: E::Baz(10.2) };
assert_eq!( assert_eq!(
encode!(v), encode!(v),
map! { a: Float(10.2) } map! { a, Float(10.2) }
); );
assert_eq!(v, decode!(Table(encode!(v)))); assert_eq!(v, decode!(Table(encode!(v))));
let v = Foo { a: E::Last(Foo2 { test: "test".to_string() }) }; let v = Foo { a: E::Last(Foo2 { test: "test".to_string() }) };
assert_eq!( assert_eq!(
encode!(v), encode!(v),
map! { a: Table(map! { test: Value::String("test".to_string()) }) } map! { a, Table(map! { test, Value::String("test".to_string()) }) }
); );
assert_eq!(v, decode!(Table(encode!(v)))); assert_eq!(v, decode!(Table(encode!(v))));
} }
@ -1130,13 +1132,13 @@ mod tests {
let v = Foo { a: 2 }; let v = Foo { a: 2 };
let mut d = Decoder::new(Table(map! { let mut d = Decoder::new(Table(map! {
a: Integer(2), a, Integer(2),
b: Integer(5) b, Integer(5)
})); }));
assert_eq!(v, Decodable::decode(&mut d).unwrap()); assert_eq!(v, Decodable::decode(&mut d).unwrap());
assert_eq!(d.toml, Some(Table(map! { assert_eq!(d.toml, Some(Table(map! {
b: Integer(5) b, Integer(5)
}))); })));
} }
@ -1149,16 +1151,16 @@ mod tests {
let v = Foo { a: Bar { a: 2 } }; let v = Foo { a: Bar { a: 2 } };
let mut d = Decoder::new(Table(map! { let mut d = Decoder::new(Table(map! {
a: Table(map! { a, Table(map! {
a: Integer(2), a, Integer(2),
b: Integer(5) b, Integer(5)
}) })
})); }));
assert_eq!(v, Decodable::decode(&mut d).unwrap()); assert_eq!(v, Decodable::decode(&mut d).unwrap());
assert_eq!(d.toml, Some(Table(map! { assert_eq!(d.toml, Some(Table(map! {
a: Table(map! { a, Table(map! {
b: Integer(5) b, Integer(5)
}) })
}))); })));
} }
@ -1172,8 +1174,8 @@ mod tests {
let v = Foo { a: Bar { a: 2 } }; let v = Foo { a: Bar { a: 2 } };
let mut d = Decoder::new(Table(map! { let mut d = Decoder::new(Table(map! {
a: Table(map! { a, Table(map! {
a: Integer(2) a, Integer(2)
}) })
})); }));
assert_eq!(v, Decodable::decode(&mut d).unwrap()); assert_eq!(v, Decodable::decode(&mut d).unwrap());
@ -1186,10 +1188,10 @@ mod tests {
#[derive(RustcEncodable, RustcDecodable, PartialEq, Show)] #[derive(RustcEncodable, RustcDecodable, PartialEq, Show)]
struct Foo { a: BTreeMap<String, String> } struct Foo { a: BTreeMap<String, String> }
let v = Foo { a: map! { a: "foo".to_string() } }; let v = Foo { a: map! { a, "foo".to_string() } };
let mut d = Decoder::new(Table(map! { let mut d = Decoder::new(Table(map! {
a: Table(map! { a, Table(map! {
a: Value::String("foo".to_string()) a, Value::String("foo".to_string())
}) })
})); }));
assert_eq!(v, Decodable::decode(&mut d).unwrap()); assert_eq!(v, Decodable::decode(&mut d).unwrap());
@ -1204,7 +1206,7 @@ mod tests {
let v = Foo { a: vec!["a".to_string()] }; let v = Foo { a: vec!["a".to_string()] };
let mut d = Decoder::new(Table(map! { let mut d = Decoder::new(Table(map! {
a: Array(vec![Value::String("a".to_string())]) a, Array(vec![Value::String("a".to_string())])
})); }));
assert_eq!(v, Decodable::decode(&mut d).unwrap()); assert_eq!(v, Decodable::decode(&mut d).unwrap());
@ -1218,7 +1220,7 @@ mod tests {
let v = Foo { a: Some(vec![]) }; let v = Foo { a: Some(vec![]) };
let mut d = Decoder::new(Table(map! { let mut d = Decoder::new(Table(map! {
a: Array(vec![]) a, Array(vec![])
})); }));
assert_eq!(v, Decodable::decode(&mut d).unwrap()); assert_eq!(v, Decodable::decode(&mut d).unwrap());
@ -1234,16 +1236,16 @@ mod tests {
let v = Foo { a: vec![Bar { a: 1 }] }; let v = Foo { a: vec![Bar { a: 1 }] };
let mut d = Decoder::new(Table(map! { let mut d = Decoder::new(Table(map! {
a: Array(vec![Table(map! { a, Array(vec![Table(map! {
a: Integer(1), a, Integer(1),
b: Integer(2) b, Integer(2)
})]) })])
})); }));
assert_eq!(v, Decodable::decode(&mut d).unwrap()); assert_eq!(v, Decodable::decode(&mut d).unwrap());
assert_eq!(d.toml, Some(Table(map! { assert_eq!(d.toml, Some(Table(map! {
a: Array(vec![Table(map! { a, Array(vec![Table(map! {
b: Integer(2) b, Integer(2)
})]) })])
}))); })));
} }
@ -1273,7 +1275,7 @@ mod tests {
let v = Foo { a: Some(vec![]) }; let v = Foo { a: Some(vec![]) };
let mut d = Decoder::new(Table(map! { let mut d = Decoder::new(Table(map! {
a: Array(vec![]) a, Array(vec![])
})); }));
assert_eq!(v, Decodable::decode(&mut d).unwrap()); assert_eq!(v, Decodable::decode(&mut d).unwrap());
} }

View file

@ -1,6 +1,7 @@
use std::fmt; use std::fmt;
use Table as TomlTable; use Table as TomlTable;
use Array as TomlArray;
use Value::{self, String, Integer, Float, Boolean, Datetime, Array, Table}; use Value::{self, String, Integer, Float, Boolean, Datetime, Array, Table};
struct Printer<'a, 'b:'a> { struct Printer<'a, 'b:'a> {
@ -8,7 +9,7 @@ struct Printer<'a, 'b:'a> {
stack: Vec<&'a str>, stack: Vec<&'a str>,
} }
impl fmt::Show for Value { impl fmt::String for Value {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match *self { match *self {
String(ref s) => { String(ref s) => {
@ -39,7 +40,10 @@ impl fmt::Show for Value {
let mut p = Printer { output: f, stack: Vec::new() }; let mut p = Printer { output: f, stack: Vec::new() };
p.print(t) p.print(t)
} }
Array(ref a) => write!(f, "{}", a), Array(ref a) => {
let mut p = Printer { output: f, stack: Vec::new() };
p.print_array(a)
},
} }
} }
} }
@ -89,6 +93,20 @@ impl<'a, 'b> Printer<'a, 'b> {
} }
Ok(()) Ok(())
} }
fn print_array(&mut self, array: &'a TomlArray) -> fmt::Result {
try!(self.output.write_str("["));
let mut first = true;
for item in array.iter() {
if first {
first = false;
} else {
try!(self.output.write_str(", "));
}
try!((&item as &fmt::String).fmt(self.output));
}
self.output.write_str("]")
}
} }
#[cfg(test)] #[cfg(test)]
@ -98,7 +116,7 @@ mod tests {
use Value::{String, Integer, Float, Boolean, Datetime, Array, Table}; use Value::{String, Integer, Float, Boolean, Datetime, Array, Table};
use std::collections::BTreeMap; use std::collections::BTreeMap;
macro_rules! map( ($($k:expr: $v:expr),*) => ({ macro_rules! map( ($($k:expr, $v:expr),*) => ({
let mut _m = BTreeMap::new(); let mut _m = BTreeMap::new();
$(_m.insert($k.to_string(), $v);)* $(_m.insert($k.to_string(), $v);)*
_m _m
@ -128,12 +146,12 @@ mod tests {
fn table() { fn table() {
assert_eq!(Table(map! { }).to_string().as_slice(), assert_eq!(Table(map! { }).to_string().as_slice(),
""); "");
assert_eq!(Table(map! { "test": Integer(2) }).to_string().as_slice(), assert_eq!(Table(map! { "test", Integer(2) }).to_string().as_slice(),
"test = 2\n"); "test = 2\n");
assert_eq!(Table(map! { assert_eq!(Table(map! {
"test": Integer(2), "test", Integer(2),
"test2": Table(map! { "test2", Table(map! {
"test": String("wut".to_string()) "test", String("wut".to_string())
}) })
}).to_string().as_slice(), }).to_string().as_slice(),
"test = 2\n\ "test = 2\n\
@ -141,9 +159,9 @@ mod tests {
[test2]\n\ [test2]\n\
test = \"wut\"\n"); test = \"wut\"\n");
assert_eq!(Table(map! { assert_eq!(Table(map! {
"test": Integer(2), "test", Integer(2),
"test2": Table(map! { "test2", Table(map! {
"test": String("wut".to_string()) "test", String("wut".to_string())
}) })
}).to_string().as_slice(), }).to_string().as_slice(),
"test = 2\n\ "test = 2\n\
@ -151,9 +169,9 @@ mod tests {
[test2]\n\ [test2]\n\
test = \"wut\"\n"); test = \"wut\"\n");
assert_eq!(Table(map! { assert_eq!(Table(map! {
"test": Integer(2), "test", Integer(2),
"test2": Array(vec![Table(map! { "test2", Array(vec![Table(map! {
"test": String("wut".to_string()) "test", String("wut".to_string())
})]) })])
}).to_string().as_slice(), }).to_string().as_slice(),
"test = 2\n\ "test = 2\n\

View file

@ -46,7 +46,7 @@ fn to_json(toml: Value) -> Json {
fn run(toml: &str, json: &str) { fn run(toml: &str, json: &str) {
let mut p = Parser::new(toml); let mut p = Parser::new(toml);
let table = p.parse(); let table = p.parse();
assert!(p.errors.len() == 0, "had_errors: {}", assert!(p.errors.len() == 0, "had_errors: {:?}",
p.errors.iter().map(|e| { p.errors.iter().map(|e| {
(e.desc.clone(), toml.slice(e.lo - 5, e.hi + 5)) (e.desc.clone(), toml.slice(e.lo - 5, e.hi + 5))
}).collect::<Vec<(String, &str)>>()); }).collect::<Vec<(String, &str)>>());