cargo fmt

This commit is contained in:
Eric Huss 2019-05-08 17:45:39 -07:00
parent 0737f0b27a
commit 8f115c98d3
14 changed files with 853 additions and 527 deletions

View file

@ -14,12 +14,12 @@
//! [`BTreeMap`]: https://doc.rust-lang.org/std/collections/struct.BTreeMap.html //! [`BTreeMap`]: https://doc.rust-lang.org/std/collections/struct.BTreeMap.html
//! [`LinkedHashMap`]: https://docs.rs/linked-hash-map/*/linked_hash_map/struct.LinkedHashMap.html //! [`LinkedHashMap`]: https://docs.rs/linked-hash-map/*/linked_hash_map/struct.LinkedHashMap.html
use serde::{de, ser};
use std::fmt::{self, Debug};
use crate::value::Value; use crate::value::Value;
use serde::{de, ser};
use std::borrow::Borrow;
use std::fmt::{self, Debug};
use std::hash::Hash; use std::hash::Hash;
use std::iter::FromIterator; use std::iter::FromIterator;
use std::borrow::Borrow;
use std::ops; use std::ops;
#[cfg(not(feature = "preserve_order"))] #[cfg(not(feature = "preserve_order"))]
@ -144,10 +144,10 @@ impl Map<String, Value> {
where where
S: Into<String>, S: Into<String>,
{ {
#[cfg(not(feature = "preserve_order"))]
use std::collections::btree_map::Entry as EntryImpl;
#[cfg(feature = "preserve_order")] #[cfg(feature = "preserve_order")]
use linked_hash_map::Entry as EntryImpl; use linked_hash_map::Entry as EntryImpl;
#[cfg(not(feature = "preserve_order"))]
use std::collections::btree_map::Entry as EntryImpl;
match self.map.entry(key.into()) { match self.map.entry(key.into()) {
EntryImpl::Vacant(vacant) => Entry::Vacant(VacantEntry { vacant: vacant }), EntryImpl::Vacant(vacant) => Entry::Vacant(VacantEntry { vacant: vacant }),

View file

@ -16,7 +16,6 @@ pub use crate::datetime::{Datetime, DatetimeParseError};
pub use crate::map::Map; pub use crate::map::Map;
/// Representation of a TOML value. /// Representation of a TOML value.
#[derive(PartialEq, Clone, Debug)] #[derive(PartialEq, Clone, Debug)]
pub enum Value { pub enum Value {

View file

@ -1,5 +1,5 @@
extern crate toml;
extern crate serde; extern crate serde;
extern crate toml;
use serde::de::Deserialize; use serde::de::Deserialize;
@ -35,7 +35,10 @@ fn allow_duplicate_after_longer() {
let mut d = toml::de::Deserializer::new(s); let mut d = toml::de::Deserializer::new(s);
d.set_allow_duplicate_after_longer_table(true); d.set_allow_duplicate_after_longer_table(true);
let value = toml::Value::deserialize(&mut d).unwrap(); let value = toml::Value::deserialize(&mut d).unwrap();
assert_eq!(value["dependencies"]["openssl-sys"]["version"].as_integer(), Some(1)); assert_eq!(
value["dependencies"]["openssl-sys"]["version"].as_integer(),
Some(1)
);
assert_eq!(value["dependencies"]["libc"].as_integer(), Some(1)); assert_eq!(value["dependencies"]["libc"].as_integer(), Some(1));
assert_eq!(value["dependencies"]["bitflags"].as_integer(), Some(1)); assert_eq!(value["dependencies"]["bitflags"].as_integer(), Some(1));
} }

View file

@ -1,5 +1,6 @@
extern crate toml; extern crate toml;
#[macro_use] extern crate serde_derive; #[macro_use]
extern crate serde_derive;
#[derive(Debug, Serialize, Deserialize)] #[derive(Debug, Serialize, Deserialize)]
pub struct Recipe { pub struct Recipe {
@ -8,41 +9,47 @@ pub struct Recipe {
#[serde(default)] #[serde(default)]
pub modules: Vec<Modules>, pub modules: Vec<Modules>,
#[serde(default)] #[serde(default)]
pub packages: Vec<Packages> pub packages: Vec<Packages>,
} }
#[derive(Debug, Serialize, Deserialize)] #[derive(Debug, Serialize, Deserialize)]
pub struct Modules { pub struct Modules {
pub name: String, pub name: String,
pub version: Option<String> pub version: Option<String>,
} }
#[derive(Debug, Serialize, Deserialize)] #[derive(Debug, Serialize, Deserialize)]
pub struct Packages { pub struct Packages {
pub name: String, pub name: String,
pub version: Option<String> pub version: Option<String>,
} }
#[test] #[test]
fn both_ends() { fn both_ends() {
let recipe_works = toml::from_str::<Recipe>(r#" let recipe_works = toml::from_str::<Recipe>(
r#"
name = "testing" name = "testing"
description = "example" description = "example"
modules = [] modules = []
[[packages]] [[packages]]
name = "base" name = "base"
"#).unwrap(); "#,
)
.unwrap();
toml::to_string(&recipe_works).unwrap(); toml::to_string(&recipe_works).unwrap();
let recipe_fails = toml::from_str::<Recipe>(r#" let recipe_fails = toml::from_str::<Recipe>(
r#"
name = "testing" name = "testing"
description = "example" description = "example"
packages = [] packages = []
[[modules]] [[modules]]
name = "base" name = "base"
"#).unwrap(); "#,
)
.unwrap();
let recipe_toml = toml::Value::try_from(recipe_fails).unwrap(); let recipe_toml = toml::Value::try_from(recipe_fails).unwrap();
recipe_toml.to_string(); recipe_toml.to_string();

View file

@ -1,7 +1,7 @@
extern crate toml; extern crate toml;
use toml::Value::{String, Integer, Float, Boolean, Array, Table};
use toml::map::Map; use toml::map::Map;
use toml::Value::{Array, Boolean, Float, Integer, String, Table};
macro_rules! map( ($($k:expr => $v:expr),*) => ({ macro_rules! map( ($($k:expr => $v:expr),*) => ({
let mut _m = Map::new(); let mut _m = Map::new();
@ -11,76 +11,86 @@ macro_rules! map( ($($k:expr => $v:expr),*) => ({
#[test] #[test]
fn simple_show() { fn simple_show() {
assert_eq!(String("foo".to_string()).to_string(), assert_eq!(String("foo".to_string()).to_string(), "\"foo\"");
"\"foo\""); assert_eq!(Integer(10).to_string(), "10");
assert_eq!(Integer(10).to_string(), assert_eq!(Float(10.0).to_string(), "10.0");
"10"); assert_eq!(Float(2.4).to_string(), "2.4");
assert_eq!(Float(10.0).to_string(), assert_eq!(Boolean(true).to_string(), "true");
"10.0"); assert_eq!(Array(vec![]).to_string(), "[]");
assert_eq!(Float(2.4).to_string(), assert_eq!(Array(vec![Integer(1), Integer(2)]).to_string(), "[1, 2]");
"2.4");
assert_eq!(Boolean(true).to_string(),
"true");
assert_eq!(Array(vec![]).to_string(),
"[]");
assert_eq!(Array(vec![Integer(1), Integer(2)]).to_string(),
"[1, 2]");
} }
#[test] #[test]
fn table() { fn table() {
assert_eq!(Table(map! { }).to_string(), assert_eq!(Table(map! {}).to_string(), "");
""); assert_eq!(
assert_eq!(Table(map! { Table(map! {
"test" => Integer(2), "test" => Integer(2),
"test2" => Integer(3) }).to_string(), "test2" => Integer(3) })
"test = 2\ntest2 = 3\n"); .to_string(),
assert_eq!(Table(map! { "test = 2\ntest2 = 3\n"
);
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(), })
.to_string(),
"test = 2\n\ "test = 2\n\
\n\ \n\
[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(), })
.to_string(),
"test = 2\n\ "test = 2\n\
\n\ \n\
[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(), })
.to_string(),
"test = 2\n\ "test = 2\n\
\n\ \n\
[[test2]]\n\ [[test2]]\n\
test = \"wut\"\n"); test = \"wut\"\n"
assert_eq!(Table(map! { );
assert_eq!(
Table(map! {
"foo.bar" => Integer(2), "foo.bar" => Integer(2),
"foo\"bar" => Integer(2) "foo\"bar" => Integer(2)
}).to_string(), })
.to_string(),
"\"foo\\\"bar\" = 2\n\ "\"foo\\\"bar\" = 2\n\
\"foo.bar\" = 2\n"); \"foo.bar\" = 2\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" => Array(vec![Integer(2)]) "test" => Array(vec![Integer(2)])
})]) })])
}).to_string(), })
.to_string(),
"test = 2\n\ "test = 2\n\
\n\ \n\
[[test2]]\n\ [[test2]]\n\
test = [2]\n"); test = [2]\n"
);
let table = Table(map! { let table = Table(map! {
"test" => Integer(2), "test" => Integer(2),
"test2" => Array(vec![Table(map! { "test2" => Array(vec![Table(map! {
@ -88,15 +98,20 @@ fn table() {
Array(vec![String("foo".to_string()), String("bar".to_string())])]) Array(vec![String("foo".to_string()), String("bar".to_string())])])
})]) })])
}); });
assert_eq!(table.to_string(), assert_eq!(
table.to_string(),
"test = 2\n\ "test = 2\n\
\n\ \n\
[[test2]]\n\ [[test2]]\n\
test = [[2, 3], [\"foo\", \"bar\"]]\n"); test = [[2, 3], [\"foo\", \"bar\"]]\n"
assert_eq!(Table(map! { );
assert_eq!(
Table(map! {
"test" => Array(vec![Integer(2)]), "test" => Array(vec![Integer(2)]),
"test2" => Integer(2) "test2" => Integer(2)
}).to_string(), })
.to_string(),
"test = [2]\n\ "test = [2]\n\
test2 = 2\n"); test2 = 2\n"
);
} }

View file

@ -32,7 +32,9 @@ macro_rules! float_inf_tests {
# zero # zero
sf7 = +0.0 sf7 = +0.0
sf8 = -0.0 sf8 = -0.0
").expect("Parse infinities."); ",
)
.expect("Parse infinities.");
assert!(inf.sf1.is_infinite()); assert!(inf.sf1.is_infinite());
assert!(inf.sf1.is_sign_positive()); assert!(inf.sf1.is_sign_positive());
@ -55,7 +57,8 @@ macro_rules! float_inf_tests {
let s = toml::to_string(&inf).unwrap(); let s = toml::to_string(&inf).unwrap();
assert_eq!( assert_eq!(
s, "\ s,
"\
sf1 = inf sf1 = inf
sf2 = inf sf2 = inf
sf3 = -inf sf3 = -inf

View file

@ -34,7 +34,8 @@ fn no_unnecessary_newlines_array() {
surname: "Dough".to_string(), surname: "Dough".to_string(),
}, },
], ],
}).unwrap() })
.unwrap()
.starts_with("\n")); .starts_with("\n"));
} }
@ -49,6 +50,7 @@ fn no_unnecessary_newlines_table() {
name: "Jane".to_string(), name: "Jane".to_string(),
surname: "Dough".to_string(), surname: "Dough".to_string(),
}, },
}).unwrap() })
.unwrap()
.starts_with("\n")); .starts_with("\n"));
} }

View file

@ -12,93 +12,156 @@ macro_rules! test( ($name:ident, $toml:expr) => (
fn $name() { run($toml); } fn $name() { run($toml); }
) ); ) );
test!(array_mixed_types_arrays_and_ints, test!(
include_str!("invalid/array-mixed-types-arrays-and-ints.toml")); array_mixed_types_arrays_and_ints,
test!(array_mixed_types_ints_and_floats, include_str!("invalid/array-mixed-types-arrays-and-ints.toml")
include_str!("invalid/array-mixed-types-ints-and-floats.toml")); );
test!(array_mixed_types_strings_and_ints, test!(
include_str!("invalid/array-mixed-types-strings-and-ints.toml")); array_mixed_types_ints_and_floats,
test!(datetime_malformed_no_leads, include_str!("invalid/array-mixed-types-ints-and-floats.toml")
include_str!("invalid/datetime-malformed-no-leads.toml")); );
test!(datetime_malformed_no_secs, test!(
include_str!("invalid/datetime-malformed-no-secs.toml")); array_mixed_types_strings_and_ints,
test!(datetime_malformed_no_t, include_str!("invalid/array-mixed-types-strings-and-ints.toml")
include_str!("invalid/datetime-malformed-no-t.toml")); );
test!(datetime_malformed_with_milli, test!(
include_str!("invalid/datetime-malformed-with-milli.toml")); datetime_malformed_no_leads,
test!(duplicate_key_table, include_str!("invalid/datetime-malformed-no-leads.toml")
include_str!("invalid/duplicate-key-table.toml")); );
test!(duplicate_keys, test!(
include_str!("invalid/duplicate-keys.toml")); datetime_malformed_no_secs,
test!(duplicate_table, include_str!("invalid/datetime-malformed-no-secs.toml")
include_str!("invalid/duplicate-table.toml")); );
test!(duplicate_tables, test!(
include_str!("invalid/duplicate-tables.toml")); datetime_malformed_no_t,
test!(empty_implicit_table, include_str!("invalid/datetime-malformed-no-t.toml")
include_str!("invalid/empty-implicit-table.toml")); );
test!(empty_table, test!(
include_str!("invalid/empty-table.toml")); datetime_malformed_with_milli,
test!(float_no_leading_zero, include_str!("invalid/datetime-malformed-with-milli.toml")
include_str!("invalid/float-no-leading-zero.toml")); );
test!(float_no_suffix, test!(
include_str!("invalid/float-no-suffix.toml")); duplicate_key_table,
test!(float_no_trailing_digits, include_str!("invalid/duplicate-key-table.toml")
include_str!("invalid/float-no-trailing-digits.toml")); );
test!(key_after_array, test!(duplicate_keys, include_str!("invalid/duplicate-keys.toml"));
include_str!("invalid/key-after-array.toml")); test!(
test!(key_after_table, duplicate_table,
include_str!("invalid/key-after-table.toml")); include_str!("invalid/duplicate-table.toml")
test!(key_empty, );
include_str!("invalid/key-empty.toml")); test!(
test!(key_hash, duplicate_tables,
include_str!("invalid/key-hash.toml")); include_str!("invalid/duplicate-tables.toml")
test!(key_newline, );
include_str!("invalid/key-newline.toml")); test!(
test!(key_open_bracket, empty_implicit_table,
include_str!("invalid/key-open-bracket.toml")); include_str!("invalid/empty-implicit-table.toml")
test!(key_single_open_bracket, );
include_str!("invalid/key-single-open-bracket.toml")); test!(empty_table, include_str!("invalid/empty-table.toml"));
test!(key_space, test!(
include_str!("invalid/key-space.toml")); float_no_leading_zero,
test!(key_start_bracket, include_str!("invalid/float-no-leading-zero.toml")
include_str!("invalid/key-start-bracket.toml")); );
test!(key_two_equals, test!(
include_str!("invalid/key-two-equals.toml")); float_no_suffix,
test!(string_bad_byte_escape, include_str!("invalid/float-no-suffix.toml")
include_str!("invalid/string-bad-byte-escape.toml")); );
test!(string_bad_escape, test!(
include_str!("invalid/string-bad-escape.toml")); float_no_trailing_digits,
test!(string_bad_line_ending_escape, include_str!("invalid/float-no-trailing-digits.toml")
include_str!("invalid/string-bad-line-ending-escape.toml")); );
test!(string_byte_escapes, test!(
include_str!("invalid/string-byte-escapes.toml")); key_after_array,
test!(string_no_close, include_str!("invalid/key-after-array.toml")
include_str!("invalid/string-no-close.toml")); );
test!(table_array_implicit, test!(
include_str!("invalid/table-array-implicit.toml")); key_after_table,
test!(table_array_malformed_bracket, include_str!("invalid/key-after-table.toml")
include_str!("invalid/table-array-malformed-bracket.toml")); );
test!(table_array_malformed_empty, test!(key_empty, include_str!("invalid/key-empty.toml"));
include_str!("invalid/table-array-malformed-empty.toml")); test!(key_hash, include_str!("invalid/key-hash.toml"));
test!(table_empty, test!(key_newline, include_str!("invalid/key-newline.toml"));
include_str!("invalid/table-empty.toml")); test!(
test!(table_nested_brackets_close, key_open_bracket,
include_str!("invalid/table-nested-brackets-close.toml")); include_str!("invalid/key-open-bracket.toml")
test!(table_nested_brackets_open, );
include_str!("invalid/table-nested-brackets-open.toml")); test!(
test!(table_whitespace, key_single_open_bracket,
include_str!("invalid/table-whitespace.toml")); include_str!("invalid/key-single-open-bracket.toml")
test!(table_with_pound, );
include_str!("invalid/table-with-pound.toml")); test!(key_space, include_str!("invalid/key-space.toml"));
test!(text_after_array_entries, test!(
include_str!("invalid/text-after-array-entries.toml")); key_start_bracket,
test!(text_after_integer, include_str!("invalid/key-start-bracket.toml")
include_str!("invalid/text-after-integer.toml")); );
test!(text_after_string, test!(key_two_equals, include_str!("invalid/key-two-equals.toml"));
include_str!("invalid/text-after-string.toml")); test!(
test!(text_after_table, string_bad_byte_escape,
include_str!("invalid/text-after-table.toml")); include_str!("invalid/string-bad-byte-escape.toml")
test!(text_before_array_separator, );
include_str!("invalid/text-before-array-separator.toml")); test!(
test!(text_in_array, string_bad_escape,
include_str!("invalid/text-in-array.toml")); include_str!("invalid/string-bad-escape.toml")
);
test!(
string_bad_line_ending_escape,
include_str!("invalid/string-bad-line-ending-escape.toml")
);
test!(
string_byte_escapes,
include_str!("invalid/string-byte-escapes.toml")
);
test!(
string_no_close,
include_str!("invalid/string-no-close.toml")
);
test!(
table_array_implicit,
include_str!("invalid/table-array-implicit.toml")
);
test!(
table_array_malformed_bracket,
include_str!("invalid/table-array-malformed-bracket.toml")
);
test!(
table_array_malformed_empty,
include_str!("invalid/table-array-malformed-empty.toml")
);
test!(table_empty, include_str!("invalid/table-empty.toml"));
test!(
table_nested_brackets_close,
include_str!("invalid/table-nested-brackets-close.toml")
);
test!(
table_nested_brackets_open,
include_str!("invalid/table-nested-brackets-open.toml")
);
test!(
table_whitespace,
include_str!("invalid/table-whitespace.toml")
);
test!(
table_with_pound,
include_str!("invalid/table-with-pound.toml")
);
test!(
text_after_array_entries,
include_str!("invalid/text-after-array-entries.toml")
);
test!(
text_after_integer,
include_str!("invalid/text-after-integer.toml")
);
test!(
text_after_string,
include_str!("invalid/text-after-string.toml")
);
test!(
text_after_table,
include_str!("invalid/text-after-table.toml")
);
test!(
text_before_array_separator,
include_str!("invalid/text-before-array-separator.toml")
);
test!(text_in_array, include_str!("invalid/text-in-array.toml"));

View file

@ -3,7 +3,7 @@ extern crate toml;
use toml::Value; use toml::Value;
macro_rules! bad { macro_rules! bad {
($s:expr, $msg:expr) => ({ ($s:expr, $msg:expr) => {{
match $s.parse::<Value>() { match $s.parse::<Value>() {
Ok(s) => panic!("successfully parsed as {}", s), Ok(s) => panic!("successfully parsed as {}", s),
Err(e) => { Err(e) => {
@ -11,7 +11,7 @@ macro_rules! bad {
assert!(e.contains($msg), "error: {}", e); assert!(e.contains($msg), "error: {}", e);
} }
} }
}) }};
} }
#[test] #[test]
@ -33,7 +33,9 @@ currently handle compression, but it is abstract over all I/O readers and\r\n\
writers. Additionally, great lengths are taken to ensure that the entire\r\n\ writers. Additionally, great lengths are taken to ensure that the entire\r\n\
contents are never required to be entirely resident in memory all at once.\r\n\ contents are never required to be entirely resident in memory all at once.\r\n\
\"\"\"\ \"\"\"\
".parse::<Value>().unwrap(); "
.parse::<Value>()
.unwrap();
} }
#[test] #[test]
@ -71,7 +73,9 @@ trimmed in raw strings.
All other whitespace All other whitespace
is preserved. is preserved.
''' '''
"#.parse::<Value>().unwrap(); "#
.parse::<Value>()
.unwrap();
assert_eq!(table["bar"].as_str(), Some("\0")); assert_eq!(table["bar"].as_str(), Some("\0"));
assert_eq!(table["key1"].as_str(), Some("One\nTwo")); assert_eq!(table["key1"].as_str(), Some("One\nTwo"));
assert_eq!(table["key2"].as_str(), Some("One\nTwo")); assert_eq!(table["key2"].as_str(), Some("One\nTwo"));
@ -82,16 +86,32 @@ is preserved.
assert_eq!(table["key5"].as_str(), Some(msg)); assert_eq!(table["key5"].as_str(), Some(msg));
assert_eq!(table["key6"].as_str(), Some(msg)); assert_eq!(table["key6"].as_str(), Some(msg));
assert_eq!(table["winpath"].as_str(), Some(r"C:\Users\nodejs\templates")); assert_eq!(
assert_eq!(table["winpath2"].as_str(), Some(r"\\ServerX\admin$\system32\")); table["winpath"].as_str(),
assert_eq!(table["quoted"].as_str(), Some(r#"Tom "Dubs" Preston-Werner"#)); Some(r"C:\Users\nodejs\templates")
);
assert_eq!(
table["winpath2"].as_str(),
Some(r"\\ServerX\admin$\system32\")
);
assert_eq!(
table["quoted"].as_str(),
Some(r#"Tom "Dubs" Preston-Werner"#)
);
assert_eq!(table["regex"].as_str(), Some(r"<\i\c*\s*>")); assert_eq!(table["regex"].as_str(), Some(r"<\i\c*\s*>"));
assert_eq!(table["regex2"].as_str(), Some(r"I [dw]on't need \d{2} apples")); assert_eq!(
assert_eq!(table["lines"].as_str(), table["regex2"].as_str(),
Some("The first newline is\n\ Some(r"I [dw]on't need \d{2} apples")
);
assert_eq!(
table["lines"].as_str(),
Some(
"The first newline is\n\
trimmed in raw strings.\n\ trimmed in raw strings.\n\
All other whitespace\n\ All other whitespace\n\
is preserved.\n")); is preserved.\n"
)
);
} }
#[test] #[test]
@ -106,7 +126,9 @@ fn tables_in_arrays() {
# #
[foo.bar] [foo.bar]
#... #...
"#.parse::<Value>().unwrap(); "#
.parse::<Value>()
.unwrap();
table["foo"][0]["bar"].as_table().unwrap(); table["foo"][0]["bar"].as_table().unwrap();
table["foo"][1]["bar"].as_table().unwrap(); table["foo"][1]["bar"].as_table().unwrap();
} }
@ -114,7 +136,9 @@ fn tables_in_arrays() {
#[test] #[test]
fn empty_table() { fn empty_table() {
let table = r#" let table = r#"
[foo]"#.parse::<Value>().unwrap(); [foo]"#
.parse::<Value>()
.unwrap();
table["foo"].as_table().unwrap(); table["foo"].as_table().unwrap();
} }
@ -139,14 +163,28 @@ name = "banana"
[[fruit.variety]] [[fruit.variety]]
name = "plantain" name = "plantain"
"#.parse::<Value>().unwrap(); "#
.parse::<Value>()
.unwrap();
assert_eq!(table["fruit"][0]["name"].as_str(), Some("apple")); assert_eq!(table["fruit"][0]["name"].as_str(), Some("apple"));
assert_eq!(table["fruit"][0]["physical"]["color"].as_str(), Some("red")); assert_eq!(table["fruit"][0]["physical"]["color"].as_str(), Some("red"));
assert_eq!(table["fruit"][0]["physical"]["shape"].as_str(), Some("round")); assert_eq!(
assert_eq!(table["fruit"][0]["variety"][0]["name"].as_str(), Some("red delicious")); table["fruit"][0]["physical"]["shape"].as_str(),
assert_eq!(table["fruit"][0]["variety"][1]["name"].as_str(), Some("granny smith")); Some("round")
);
assert_eq!(
table["fruit"][0]["variety"][0]["name"].as_str(),
Some("red delicious")
);
assert_eq!(
table["fruit"][0]["variety"][1]["name"].as_str(),
Some("granny smith")
);
assert_eq!(table["fruit"][1]["name"].as_str(), Some("banana")); assert_eq!(table["fruit"][1]["name"].as_str(), Some("banana"));
assert_eq!(table["fruit"][1]["variety"][0]["name"].as_str(), Some("plantain")); assert_eq!(
table["fruit"][1]["variety"][0]["name"].as_str(),
Some("plantain")
);
} }
#[test] #[test]
@ -177,7 +215,9 @@ fn literal_eats_crlf() {
let table = " let table = "
foo = \"\"\"\\\r\n\"\"\" foo = \"\"\"\\\r\n\"\"\"
bar = \"\"\"\\\r\n \r\n \r\n a\"\"\" bar = \"\"\"\\\r\n \r\n \r\n a\"\"\"
".parse::<Value>().unwrap(); "
.parse::<Value>()
.unwrap();
assert_eq!(table["foo"].as_str(), Some("")); assert_eq!(table["foo"].as_str(), Some(""));
assert_eq!(table["bar"].as_str(), Some("a")); assert_eq!(table["bar"].as_str(), Some("a"));
} }
@ -215,12 +255,12 @@ fn bad_floats() {
#[test] #[test]
fn floats() { fn floats() {
macro_rules! t { macro_rules! t {
($actual:expr, $expected:expr) => ({ ($actual:expr, $expected:expr) => {{
let f = format!("foo = {}", $actual); let f = format!("foo = {}", $actual);
println!("{}", f); println!("{}", f);
let a = f.parse::<Value>().unwrap(); let a = f.parse::<Value>().unwrap();
assert_eq!(a["foo"].as_float().unwrap(), $expected); assert_eq!(a["foo"].as_float().unwrap(), $expected);
}) }};
} }
t!("1.0", 1.0); t!("1.0", 1.0);
@ -252,7 +292,9 @@ fn bare_key_names() {
\"\\\"\" = 3 \"\\\"\" = 3
\"character encoding\" = \"value\" \"character encoding\" = \"value\"
'ʎǝʞ' = \"value\" 'ʎǝʞ' = \"value\"
".parse::<Value>().unwrap(); "
.parse::<Value>()
.unwrap();
&a["foo"]; &a["foo"];
&a["-"]; &a["-"];
&a["_"]; &a["_"];
@ -310,7 +352,9 @@ fn table_names() {
[\"\\\"\"] [\"\\\"\"]
['a.a'] ['a.a']
['\"\"'] ['\"\"']
".parse::<Value>().unwrap(); "
.parse::<Value>()
.unwrap();
println!("{:?}", a); println!("{:?}", a);
&a["a"]["b"]; &a["a"]["b"];
&a["f f"]; &a["f f"];
@ -344,11 +388,11 @@ fn inline_tables() {
#[test] #[test]
fn number_underscores() { fn number_underscores() {
macro_rules! t { macro_rules! t {
($actual:expr, $expected:expr) => ({ ($actual:expr, $expected:expr) => {{
let f = format!("foo = {}", $actual); let f = format!("foo = {}", $actual);
let table = f.parse::<Value>().unwrap(); let table = f.parse::<Value>().unwrap();
assert_eq!(table["foo"].as_integer().unwrap(), $expected); assert_eq!(table["foo"].as_integer().unwrap(), $expected);
}) }};
} }
t!("1_0", 10); t!("1_0", 10);
@ -381,11 +425,12 @@ fn bad_strings() {
#[test] #[test]
fn empty_string() { fn empty_string() {
assert_eq!("foo = \"\"".parse::<Value>() assert_eq!(
.unwrap()["foo"] "foo = \"\"".parse::<Value>().unwrap()["foo"]
.as_str() .as_str()
.unwrap(), .unwrap(),
""); ""
);
} }
#[test] #[test]
@ -404,67 +449,94 @@ fn booleans() {
#[test] #[test]
fn bad_nesting() { fn bad_nesting() {
bad!(" bad!(
"
a = [2] a = [2]
[[a]] [[a]]
b = 5 b = 5
", "duplicate key: `a`"); ",
bad!(" "duplicate key: `a`"
);
bad!(
"
a = 1 a = 1
[a.b] [a.b]
", "duplicate key: `a`"); ",
bad!(" "duplicate key: `a`"
);
bad!(
"
a = [] a = []
[a.b] [a.b]
", "duplicate key: `a`"); ",
bad!(" "duplicate key: `a`"
);
bad!(
"
a = [] a = []
[[a.b]] [[a.b]]
", "duplicate key: `a`"); ",
bad!(" "duplicate key: `a`"
);
bad!(
"
[a] [a]
b = { c = 2, d = {} } b = { c = 2, d = {} }
[a.b] [a.b]
c = 2 c = 2
", "duplicate key: `b`"); ",
"duplicate key: `b`"
);
} }
#[test] #[test]
fn bad_table_redefine() { fn bad_table_redefine() {
bad!(" bad!(
"
[a] [a]
foo=\"bar\" foo=\"bar\"
[a.b] [a.b]
foo=\"bar\" foo=\"bar\"
[a] [a]
", "redefinition of table `a`"); ",
bad!(" "redefinition of table `a`"
);
bad!(
"
[a] [a]
foo=\"bar\" foo=\"bar\"
b = { foo = \"bar\" } b = { foo = \"bar\" }
[a] [a]
", "redefinition of table `a`"); ",
bad!(" "redefinition of table `a`"
);
bad!(
"
[a] [a]
b = {} b = {}
[a.b] [a.b]
", "duplicate key: `b`"); ",
"duplicate key: `b`"
);
bad!(" bad!(
"
[a] [a]
b = {} b = {}
[a] [a]
", "redefinition of table `a`"); ",
"redefinition of table `a`"
);
} }
#[test] #[test]
fn datetimes() { fn datetimes() {
macro_rules! t { macro_rules! t {
($actual:expr) => ({ ($actual:expr) => {{
let f = format!("foo = {}", $actual); let f = format!("foo = {}", $actual);
let toml = f.parse::<Value>().expect(&format!("failed: {}", f)); let toml = f.parse::<Value>().expect(&format!("failed: {}", f));
assert_eq!(toml["foo"].as_datetime().unwrap().to_string(), $actual); assert_eq!(toml["foo"].as_datetime().unwrap().to_string(), $actual);
}) }};
} }
t!("2016-09-09T09:09:09Z"); t!("2016-09-09T09:09:09Z");
@ -481,22 +553,37 @@ fn datetimes() {
#[test] #[test]
fn require_newline_after_value() { fn require_newline_after_value() {
bad!("0=0r=false", "invalid number at line 1"); bad!("0=0r=false", "invalid number at line 1");
bad!(r#" bad!(
r#"
0=""o=""m=""r=""00="0"q="""0"""e="""0""" 0=""o=""m=""r=""00="0"q="""0"""e="""0"""
"#, "expected newline"); "#,
bad!(r#" "expected newline"
);
bad!(
r#"
[[0000l0]] [[0000l0]]
0="0"[[0000l0]] 0="0"[[0000l0]]
0="0"[[0000l0]] 0="0"[[0000l0]]
0="0"l="0" 0="0"l="0"
"#, "expected newline"); "#,
bad!(r#" "expected newline"
);
bad!(
r#"
0=[0]00=[0,0,0]t=["0","0","0"]s=[1000-00-00T00:00:00Z,2000-00-00T00:00:00Z] 0=[0]00=[0,0,0]t=["0","0","0"]s=[1000-00-00T00:00:00Z,2000-00-00T00:00:00Z]
"#, "expected newline"); "#,
bad!(r#" "expected newline"
);
bad!(
r#"
0=0r0=0r=false 0=0r0=0r=false
"#, "invalid number at line 2"); "#,
bad!(r#" "invalid number at line 2"
);
bad!(
r#"
0=0r0=0r=falsefal=false 0=0r0=0r=falsefal=false
"#, "invalid number at line 2"); "#,
"invalid number at line 2"
);
} }

View file

@ -1,5 +1,5 @@
extern crate toml;
extern crate serde; extern crate serde;
extern crate toml;
use serde::ser::Serialize; use serde::ser::Serialize;
@ -16,7 +16,9 @@ fn no_pretty() {
let toml = NO_PRETTY; let toml = NO_PRETTY;
let value: toml::Value = toml::from_str(toml).unwrap(); let value: toml::Value = toml::from_str(toml).unwrap();
let mut result = String::with_capacity(128); let mut result = String::with_capacity(128);
value.serialize(&mut toml::Serializer::new(&mut result)).unwrap(); value
.serialize(&mut toml::Serializer::new(&mut result))
.unwrap();
println!("EXPECTED:\n{}", toml); println!("EXPECTED:\n{}", toml);
println!("\nRESULT:\n{}", result); println!("\nRESULT:\n{}", result);
assert_eq!(toml, &result); assert_eq!(toml, &result);
@ -58,13 +60,14 @@ fn pretty_std() {
let toml = PRETTY_STD; let toml = PRETTY_STD;
let value: toml::Value = toml::from_str(toml).unwrap(); let value: toml::Value = toml::from_str(toml).unwrap();
let mut result = String::with_capacity(128); let mut result = String::with_capacity(128);
value.serialize(&mut toml::Serializer::pretty(&mut result)).unwrap(); value
.serialize(&mut toml::Serializer::pretty(&mut result))
.unwrap();
println!("EXPECTED:\n{}", toml); println!("EXPECTED:\n{}", toml);
println!("\nRESULT:\n{}", result); println!("\nRESULT:\n{}", result);
assert_eq!(toml, &result); assert_eq!(toml, &result);
} }
const PRETTY_INDENT_2: &'static str = "\ const PRETTY_INDENT_2: &'static str = "\
[example] [example]
array = [ array = [
@ -110,7 +113,6 @@ oneline = \"this has no newlines.\"
text = \"\\nthis is the first line\\nthis is the second line\\n\" text = \"\\nthis is the first line\\nthis is the second line\\n\"
"; ";
#[test] #[test]
/// Test pretty indent when gotten the other way /// Test pretty indent when gotten the other way
fn pretty_indent_2_other() { fn pretty_indent_2_other() {
@ -125,7 +127,6 @@ fn pretty_indent_2_other() {
assert_eq!(toml, &result); assert_eq!(toml, &result);
} }
const PRETTY_ARRAY_NO_COMMA: &'static str = "\ const PRETTY_ARRAY_NO_COMMA: &'static str = "\
[example] [example]
array = [ array = [
@ -150,7 +151,6 @@ fn pretty_indent_array_no_comma() {
assert_eq!(toml, &result); assert_eq!(toml, &result);
} }
const PRETTY_NO_STRING: &'static str = "\ const PRETTY_NO_STRING: &'static str = "\
[example] [example]
array = [ array = [
@ -207,7 +207,9 @@ fn pretty_tricky() {
let toml = PRETTY_TRICKY; let toml = PRETTY_TRICKY;
let value: toml::Value = toml::from_str(toml).unwrap(); let value: toml::Value = toml::from_str(toml).unwrap();
let mut result = String::with_capacity(128); let mut result = String::with_capacity(128);
value.serialize(&mut toml::Serializer::pretty(&mut result)).unwrap(); value
.serialize(&mut toml::Serializer::pretty(&mut result))
.unwrap();
println!("EXPECTED:\n{}", toml); println!("EXPECTED:\n{}", toml);
println!("\nRESULT:\n{}", result); println!("\nRESULT:\n{}", result);
assert_eq!(toml, &result); assert_eq!(toml, &result);
@ -231,7 +233,9 @@ fn pretty_table_array() {
let toml = PRETTY_TABLE_ARRAY; let toml = PRETTY_TABLE_ARRAY;
let value: toml::Value = toml::from_str(toml).unwrap(); let value: toml::Value = toml::from_str(toml).unwrap();
let mut result = String::with_capacity(128); let mut result = String::with_capacity(128);
value.serialize(&mut toml::Serializer::pretty(&mut result)).unwrap(); value
.serialize(&mut toml::Serializer::pretty(&mut result))
.unwrap();
println!("EXPECTED:\n{}", toml); println!("EXPECTED:\n{}", toml);
println!("\nRESULT:\n{}", result); println!("\nRESULT:\n{}", result);
assert_eq!(toml, &result); assert_eq!(toml, &result);
@ -255,7 +259,9 @@ fn table_array() {
let toml = TABLE_ARRAY; let toml = TABLE_ARRAY;
let value: toml::Value = toml::from_str(toml).unwrap(); let value: toml::Value = toml::from_str(toml).unwrap();
let mut result = String::with_capacity(128); let mut result = String::with_capacity(128);
value.serialize(&mut toml::Serializer::new(&mut result)).unwrap(); value
.serialize(&mut toml::Serializer::new(&mut result))
.unwrap();
println!("EXPECTED:\n{}", toml); println!("EXPECTED:\n{}", toml);
println!("\nRESULT:\n{}", result); println!("\nRESULT:\n{}", result);
assert_eq!(toml, &result); assert_eq!(toml, &result);

View file

@ -4,22 +4,24 @@ extern crate toml;
#[macro_use] #[macro_use]
extern crate serde_derive; extern crate serde_derive;
use std::collections::{BTreeMap, HashSet};
use serde::{Deserialize, Deserializer}; use serde::{Deserialize, Deserializer};
use std::collections::{BTreeMap, HashSet};
use toml::Value;
use toml::Value::{Table, Integer, Array, Float};
use toml::map::Map; use toml::map::Map;
use toml::Value;
use toml::Value::{Array, Float, Integer, Table};
macro_rules! t { macro_rules! t {
($e:expr) => (match $e { ($e:expr) => {
match $e {
Ok(t) => t, Ok(t) => t,
Err(e) => panic!("{} failed with {}", stringify!($e), e), Err(e) => panic!("{} failed with {}", stringify!($e), e),
}) }
};
} }
macro_rules! equivalent { macro_rules! equivalent {
($literal:expr, $toml:expr,) => ({ ($literal:expr, $toml:expr,) => {{
let toml = $toml; let toml = $toml;
let literal = $literal; let literal = $literal;
@ -38,17 +40,16 @@ macro_rules! equivalent {
assert_eq!(literal, t!(toml::from_str(&toml.to_string()))); assert_eq!(literal, t!(toml::from_str(&toml.to_string())));
println!("toml, from_str(toml)"); println!("toml, from_str(toml)");
assert_eq!(toml, t!(toml::from_str(&toml.to_string()))); assert_eq!(toml, t!(toml::from_str(&toml.to_string())));
}) }};
} }
macro_rules! error { macro_rules! error {
($ty:ty, $toml:expr, $error:expr) => ({ ($ty:ty, $toml:expr, $error:expr) => {{
println!("attempting parsing"); println!("attempting parsing");
match toml::from_str::<$ty>(&$toml.to_string()) { match toml::from_str::<$ty>(&$toml.to_string()) {
Ok(_) => panic!("successful"), Ok(_) => panic!("successful"),
Err(e) => { Err(e) => {
assert!(e.to_string().contains($error), assert!(e.to_string().contains($error), "bad error: {}", e);
"bad error: {}", e);
} }
} }
@ -56,11 +57,10 @@ macro_rules! error {
match $toml.try_into::<$ty>() { match $toml.try_into::<$ty>() {
Ok(_) => panic!("successful"), Ok(_) => panic!("successful"),
Err(e) => { Err(e) => {
assert!(e.to_string().contains($error), assert!(e.to_string().contains($error), "bad error: {}", e);
"bad error: {}", e);
} }
} }
}) }};
} }
macro_rules! map( ($($k:ident: $v:expr),*) => ({ macro_rules! map( ($($k:ident: $v:expr),*) => ({
@ -72,12 +72,11 @@ macro_rules! map( ($($k:ident: $v:expr),*) => ({
#[test] #[test]
fn smoke() { fn smoke() {
#[derive(Serialize, Deserialize, PartialEq, Debug, Clone)] #[derive(Serialize, Deserialize, PartialEq, Debug, Clone)]
struct Foo { a: isize } struct Foo {
a: isize,
}
equivalent!( equivalent!(Foo { a: 2 }, Table(map! { a: Integer(2) }),);
Foo { a: 2 },
Table(map! { a: Integer(2) }),
);
} }
#[test] #[test]
@ -109,9 +108,14 @@ fn smoke_hyphen() {
#[test] #[test]
fn nested() { fn nested() {
#[derive(Serialize, Deserialize, PartialEq, Debug, Clone)] #[derive(Serialize, Deserialize, PartialEq, Debug, Clone)]
struct Foo { a: isize, b: Bar } struct Foo {
a: isize,
b: Bar,
}
#[derive(Serialize, Deserialize, PartialEq, Debug, Clone)] #[derive(Serialize, Deserialize, PartialEq, Debug, Clone)]
struct Bar { a: String } struct Bar {
a: String,
}
equivalent! { equivalent! {
Foo { a: 2, b: Bar { a: "test".to_string() } }, Foo { a: 2, b: Bar { a: "test".to_string() } },
@ -153,7 +157,9 @@ fn application_decode_error() {
#[test] #[test]
fn array() { fn array() {
#[derive(Serialize, Deserialize, PartialEq, Debug, Clone)] #[derive(Serialize, Deserialize, PartialEq, Debug, Clone)]
struct Foo { a: Vec<isize> } struct Foo {
a: Vec<isize>,
}
equivalent! { equivalent! {
Foo { a: vec![1, 2, 3, 4] }, Foo { a: vec![1, 2, 3, 4] },
@ -239,9 +245,13 @@ fn hashmap() {
#[test] #[test]
fn table_array() { fn table_array() {
#[derive(Serialize, Deserialize, PartialEq, Debug, Clone)] #[derive(Serialize, Deserialize, PartialEq, Debug, Clone)]
struct Foo { a: Vec<Bar>, } struct Foo {
a: Vec<Bar>,
}
#[derive(Serialize, Deserialize, PartialEq, Debug, Clone)] #[derive(Serialize, Deserialize, PartialEq, Debug, Clone)]
struct Bar { a: isize } struct Bar {
a: isize,
}
equivalent! { equivalent! {
Foo { a: vec![Bar { a: 1 }, Bar { a: 2 }] }, Foo { a: vec![Bar { a: 1 }, Bar { a: 2 }] },
@ -258,7 +268,9 @@ fn table_array() {
fn type_errors() { fn type_errors() {
#[derive(Deserialize)] #[derive(Deserialize)]
#[allow(dead_code)] #[allow(dead_code)]
struct Foo { bar: isize } struct Foo {
bar: isize,
}
error! { error! {
Foo, Foo,
@ -270,7 +282,9 @@ fn type_errors() {
#[derive(Deserialize)] #[derive(Deserialize)]
#[allow(dead_code)] #[allow(dead_code)]
struct Bar { foo: Foo } struct Bar {
foo: Foo,
}
error! { error! {
Bar, Bar,
@ -286,7 +300,9 @@ fn type_errors() {
#[test] #[test]
fn missing_errors() { fn missing_errors() {
#[derive(Serialize, Deserialize, PartialEq, Debug)] #[derive(Serialize, Deserialize, PartialEq, Debug)]
struct Foo { bar: isize } struct Foo {
bar: isize,
}
error! { error! {
Foo, Foo,
@ -298,7 +314,9 @@ fn missing_errors() {
#[test] #[test]
fn parse_enum() { fn parse_enum() {
#[derive(Serialize, Deserialize, PartialEq, Debug, Clone)] #[derive(Serialize, Deserialize, PartialEq, Debug, Clone)]
struct Foo { a: E } struct Foo {
a: E,
}
#[derive(Serialize, Deserialize, PartialEq, Debug, Clone)] #[derive(Serialize, Deserialize, PartialEq, Debug, Clone)]
#[serde(untagged)] #[serde(untagged)]
enum E { enum E {
@ -330,7 +348,9 @@ fn parse_enum() {
#[test] #[test]
fn parse_enum_string() { fn parse_enum_string() {
#[derive(Serialize, Deserialize, PartialEq, Debug, Clone)] #[derive(Serialize, Deserialize, PartialEq, Debug, Clone)]
struct Foo { a: Sort } struct Foo {
a: Sort,
}
#[derive(Serialize, Deserialize, PartialEq, Debug, Clone)] #[derive(Serialize, Deserialize, PartialEq, Debug, Clone)]
#[serde(rename_all = "lowercase")] #[serde(rename_all = "lowercase")]
@ -343,7 +363,6 @@ fn parse_enum_string() {
Foo { a: Sort::Desc }, Foo { a: Sort::Desc },
Table(map! { a: Value::String("desc".to_string()) }), Table(map! { a: Value::String("desc".to_string()) }),
} }
} }
// #[test] // #[test]
@ -474,7 +493,9 @@ fn parse_enum_string() {
#[test] #[test]
fn empty_arrays() { fn empty_arrays() {
#[derive(Serialize, Deserialize, PartialEq, Debug, Clone)] #[derive(Serialize, Deserialize, PartialEq, Debug, Clone)]
struct Foo { a: Vec<Bar> } struct Foo {
a: Vec<Bar>,
}
#[derive(Serialize, Deserialize, PartialEq, Debug, Clone)] #[derive(Serialize, Deserialize, PartialEq, Debug, Clone)]
struct Bar; struct Bar;
@ -487,7 +508,9 @@ fn empty_arrays() {
#[test] #[test]
fn empty_arrays2() { fn empty_arrays2() {
#[derive(Serialize, Deserialize, PartialEq, Debug, Clone)] #[derive(Serialize, Deserialize, PartialEq, Debug, Clone)]
struct Foo { a: Option<Vec<Bar>> } struct Foo {
a: Option<Vec<Bar>>,
}
#[derive(Serialize, Deserialize, PartialEq, Debug, Clone)] #[derive(Serialize, Deserialize, PartialEq, Debug, Clone)]
struct Bar; struct Bar;
@ -505,7 +528,9 @@ fn empty_arrays2() {
#[test] #[test]
fn extra_keys() { fn extra_keys() {
#[derive(Serialize, Deserialize)] #[derive(Serialize, Deserialize)]
struct Foo { a: isize } struct Foo {
a: isize,
}
let toml = Table(map! { a: Integer(2), b: Integer(2) }); let toml = Table(map! { a: Integer(2), b: Integer(2) });
assert!(toml.clone().try_into::<Foo>().is_ok()); assert!(toml.clone().try_into::<Foo>().is_ok());
@ -516,7 +541,7 @@ fn extra_keys() {
fn newtypes() { fn newtypes() {
#[derive(Deserialize, Serialize, PartialEq, Debug, Clone)] #[derive(Deserialize, Serialize, PartialEq, Debug, Clone)]
struct A { struct A {
b: B b: B,
} }
#[derive(Deserialize, Serialize, PartialEq, Debug, Clone)] #[derive(Deserialize, Serialize, PartialEq, Debug, Clone)]
@ -532,7 +557,7 @@ fn newtypes() {
fn newtypes2() { fn newtypes2() {
#[derive(Deserialize, Serialize, PartialEq, Debug, Clone)] #[derive(Deserialize, Serialize, PartialEq, Debug, Clone)]
struct A { struct A {
b: B b: B,
} }
#[derive(Deserialize, Serialize, PartialEq, Debug, Clone)] #[derive(Deserialize, Serialize, PartialEq, Debug, Clone)]
@ -542,7 +567,7 @@ fn newtypes2() {
struct C { struct C {
x: u32, x: u32,
y: u32, y: u32,
z: u32 z: u32,
} }
equivalent! { equivalent! {
@ -572,7 +597,10 @@ fn table_structs_empty() {
expected.insert("baz".to_string(), CanBeEmpty::default()); expected.insert("baz".to_string(), CanBeEmpty::default());
expected.insert( expected.insert(
"bazv".to_string(), "bazv".to_string(),
CanBeEmpty {a: Some("foo".to_string()), b: None}, CanBeEmpty {
a: Some("foo".to_string()),
b: None,
},
); );
expected.insert("foo".to_string(), CanBeEmpty::default()); expected.insert("foo".to_string(), CanBeEmpty::default());
assert_eq!(value, expected); assert_eq!(value, expected);
@ -583,7 +611,7 @@ fn table_structs_empty() {
fn fixed_size_array() { fn fixed_size_array() {
#[derive(Serialize, Deserialize, PartialEq, Debug, Clone)] #[derive(Serialize, Deserialize, PartialEq, Debug, Clone)]
struct Entity { struct Entity {
pos: [i32; 2] pos: [i32; 2],
} }
equivalent! { equivalent! {
@ -644,10 +672,13 @@ fn homogeneous_tuple_struct() {
fn json_interoperability() { fn json_interoperability() {
#[derive(Serialize, Deserialize)] #[derive(Serialize, Deserialize)]
struct Foo { struct Foo {
any: toml::Value any: toml::Value,
} }
let _foo: Foo = serde_json::from_str(r#" let _foo: Foo = serde_json::from_str(
r#"
{"any":1} {"any":1}
"#).unwrap(); "#,
)
.unwrap();
} }

View file

@ -3,9 +3,9 @@ extern crate toml;
#[macro_use] #[macro_use]
extern crate serde_derive; extern crate serde_derive;
use toml::Spanned;
use toml::value::Datetime;
use std::collections::HashMap; use std::collections::HashMap;
use toml::value::Datetime;
use toml::Spanned;
/// A set of good datetimes. /// A set of good datetimes.
pub fn good_datetimes() -> Vec<&'static str> { pub fn good_datetimes() -> Vec<&'static str> {
@ -31,7 +31,10 @@ fn test_spanned_field() {
foo: Spanned<T>, foo: Spanned<T>,
} }
fn good<'de, T>(s: &'de str, expected: &str) where T: serde::Deserialize<'de> { fn good<'de, T>(s: &'de str, expected: &str)
where
T: serde::Deserialize<'de>,
{
let foo: Foo<T> = toml::from_str(s).unwrap(); let foo: Foo<T> = toml::from_str(s).unwrap();
assert_eq!(6, foo.foo.start()); assert_eq!(6, foo.foo.start());
@ -46,18 +49,12 @@ fn test_spanned_field() {
// table // table
good::<HashMap<String, u32>>( good::<HashMap<String, u32>>(
"foo = {\"foo\" = 42, \"bar\" = 42}", "foo = {\"foo\" = 42, \"bar\" = 42}",
"{\"foo\" = 42, \"bar\" = 42}" "{\"foo\" = 42, \"bar\" = 42}",
); );
// array // array
good::<Vec<u32>>( good::<Vec<u32>>("foo = [0, 1, 2, 3, 4]", "[0, 1, 2, 3, 4]");
"foo = [0, 1, 2, 3, 4]",
"[0, 1, 2, 3, 4]"
);
// datetime // datetime
good::<String>( good::<String>("foo = \"1997-09-09T09:09:09Z\"", "\"1997-09-09T09:09:09Z\"");
"foo = \"1997-09-09T09:09:09Z\"",
"\"1997-09-09T09:09:09Z\""
);
for expected in good_datetimes() { for expected in good_datetimes() {
let s = format!("foo = {}", expected); let s = format!("foo = {}", expected);

View file

@ -19,7 +19,9 @@ enum Value {
#[test] #[test]
fn always_works() { fn always_works() {
let mut a = A { vals: HashMap::new() }; let mut a = A {
vals: HashMap::new(),
};
a.vals.insert("foo", Value::Int(0)); a.vals.insert("foo", Value::Int(0));
let mut sub = HashMap::new(); let mut sub = HashMap::new();

View file

@ -1,10 +1,10 @@
extern crate toml;
extern crate serde; extern crate serde;
extern crate serde_json; extern crate serde_json;
extern crate toml;
use toml::{Value as Toml, to_string_pretty};
use serde::ser::Serialize; use serde::ser::Serialize;
use serde_json::Value as Json; use serde_json::Value as Json;
use toml::{to_string_pretty, Value as Toml};
fn to_json(toml: toml::Value) -> Json { fn to_json(toml: toml::Value) -> Json {
fn doit(s: &str, json: Json) -> Json { fn doit(s: &str, json: Json) -> Json {
@ -17,11 +17,18 @@ fn to_json(toml: toml::Value) -> Json {
match toml { match toml {
Toml::String(s) => doit("string", Json::String(s)), Toml::String(s) => doit("string", Json::String(s)),
Toml::Integer(i) => doit("integer", Json::String(i.to_string())), Toml::Integer(i) => doit("integer", Json::String(i.to_string())),
Toml::Float(f) => doit("float", Json::String({ Toml::Float(f) => doit(
"float",
Json::String({
let s = format!("{:.15}", f); let s = format!("{:.15}", f);
let s = format!("{}", s.trim_end_matches('0')); let s = format!("{}", s.trim_end_matches('0'));
if s.ends_with('.') {format!("{}0", s)} else {s} if s.ends_with('.') {
})), format!("{}0", s)
} else {
s
}
}),
),
Toml::Boolean(b) => doit("bool", Json::String(format!("{}", b))), Toml::Boolean(b) => doit("bool", Json::String(format!("{}", b))),
Toml::Datetime(s) => doit("datetime", Json::String(s.to_string())), Toml::Datetime(s) => doit("datetime", Json::String(s.to_string())),
Toml::Array(arr) => { Toml::Array(arr) => {
@ -30,7 +37,11 @@ fn to_json(toml: toml::Value) -> Json {
_ => false, _ => false,
}; };
let json = Json::Array(arr.into_iter().map(to_json).collect()); let json = Json::Array(arr.into_iter().map(to_json).collect());
if is_table {json} else {doit("array", json)} if is_table {
json
} else {
doit("array", json)
}
} }
Toml::Table(table) => { Toml::Table(table) => {
let mut map = serde_json::Map::new(); let mut map = serde_json::Map::new();
@ -91,10 +102,12 @@ fn run(toml_raw: &str, json_raw: &str) {
// Assert toml == json // Assert toml == json
let toml_json = to_json(toml.clone()); let toml_json = to_json(toml.clone());
assert!(json == toml_json, assert!(
json == toml_json,
"expected\n{}\ngot\n{}\n", "expected\n{}\ngot\n{}\n",
serde_json::to_string_pretty(&json).unwrap(), serde_json::to_string_pretty(&json).unwrap(),
serde_json::to_string_pretty(&toml_json).unwrap()); serde_json::to_string_pretty(&toml_json).unwrap()
);
// Assert round trip // Assert round trip
println!("round trip parse: {}", toml); println!("round trip parse: {}", toml);
@ -108,152 +121,250 @@ macro_rules! test( ($name:ident, $toml:expr, $json:expr) => (
fn $name() { run($toml, $json); } fn $name() { run($toml, $json); }
) ); ) );
test!(array_empty, test!(
array_empty,
include_str!("valid/array-empty.toml"), include_str!("valid/array-empty.toml"),
include_str!("valid/array-empty.json")); include_str!("valid/array-empty.json")
test!(array_nospaces, );
test!(
array_nospaces,
include_str!("valid/array-nospaces.toml"), include_str!("valid/array-nospaces.toml"),
include_str!("valid/array-nospaces.json")); include_str!("valid/array-nospaces.json")
test!(arrays_hetergeneous, );
test!(
arrays_hetergeneous,
include_str!("valid/arrays-hetergeneous.toml"), include_str!("valid/arrays-hetergeneous.toml"),
include_str!("valid/arrays-hetergeneous.json")); include_str!("valid/arrays-hetergeneous.json")
test!(arrays, );
test!(
arrays,
include_str!("valid/arrays.toml"), include_str!("valid/arrays.toml"),
include_str!("valid/arrays.json")); include_str!("valid/arrays.json")
test!(arrays_nested, );
test!(
arrays_nested,
include_str!("valid/arrays-nested.toml"), include_str!("valid/arrays-nested.toml"),
include_str!("valid/arrays-nested.json")); include_str!("valid/arrays-nested.json")
test!(empty, );
test!(
empty,
include_str!("valid/empty.toml"), include_str!("valid/empty.toml"),
include_str!("valid/empty.json")); include_str!("valid/empty.json")
test!(bool, );
test!(
bool,
include_str!("valid/bool.toml"), include_str!("valid/bool.toml"),
include_str!("valid/bool.json")); include_str!("valid/bool.json")
test!(comments_everywhere, );
test!(
comments_everywhere,
include_str!("valid/comments-everywhere.toml"), include_str!("valid/comments-everywhere.toml"),
include_str!("valid/comments-everywhere.json")); include_str!("valid/comments-everywhere.json")
test!(datetime, );
test!(
datetime,
include_str!("valid/datetime.toml"), include_str!("valid/datetime.toml"),
include_str!("valid/datetime.json")); include_str!("valid/datetime.json")
test!(example, );
test!(
example,
include_str!("valid/example.toml"), include_str!("valid/example.toml"),
include_str!("valid/example.json")); include_str!("valid/example.json")
test!(float, );
test!(
float,
include_str!("valid/float.toml"), include_str!("valid/float.toml"),
include_str!("valid/float.json")); include_str!("valid/float.json")
test!(implicit_and_explicit_after, );
test!(
implicit_and_explicit_after,
include_str!("valid/implicit-and-explicit-after.toml"), include_str!("valid/implicit-and-explicit-after.toml"),
include_str!("valid/implicit-and-explicit-after.json")); include_str!("valid/implicit-and-explicit-after.json")
test!(implicit_and_explicit_before, );
test!(
implicit_and_explicit_before,
include_str!("valid/implicit-and-explicit-before.toml"), include_str!("valid/implicit-and-explicit-before.toml"),
include_str!("valid/implicit-and-explicit-before.json")); include_str!("valid/implicit-and-explicit-before.json")
test!(implicit_groups, );
test!(
implicit_groups,
include_str!("valid/implicit-groups.toml"), include_str!("valid/implicit-groups.toml"),
include_str!("valid/implicit-groups.json")); include_str!("valid/implicit-groups.json")
test!(integer, );
test!(
integer,
include_str!("valid/integer.toml"), include_str!("valid/integer.toml"),
include_str!("valid/integer.json")); include_str!("valid/integer.json")
test!(key_equals_nospace, );
test!(
key_equals_nospace,
include_str!("valid/key-equals-nospace.toml"), include_str!("valid/key-equals-nospace.toml"),
include_str!("valid/key-equals-nospace.json")); include_str!("valid/key-equals-nospace.json")
test!(key_space, );
test!(
key_space,
include_str!("valid/key-space.toml"), include_str!("valid/key-space.toml"),
include_str!("valid/key-space.json")); include_str!("valid/key-space.json")
test!(key_special_chars, );
test!(
key_special_chars,
include_str!("valid/key-special-chars.toml"), include_str!("valid/key-special-chars.toml"),
include_str!("valid/key-special-chars.json")); include_str!("valid/key-special-chars.json")
test!(key_with_pound, );
test!(
key_with_pound,
include_str!("valid/key-with-pound.toml"), include_str!("valid/key-with-pound.toml"),
include_str!("valid/key-with-pound.json")); include_str!("valid/key-with-pound.json")
test!(long_float, );
test!(
long_float,
include_str!("valid/long-float.toml"), include_str!("valid/long-float.toml"),
include_str!("valid/long-float.json")); include_str!("valid/long-float.json")
test!(long_integer, );
test!(
long_integer,
include_str!("valid/long-integer.toml"), include_str!("valid/long-integer.toml"),
include_str!("valid/long-integer.json")); include_str!("valid/long-integer.json")
test!(multiline_string, );
test!(
multiline_string,
include_str!("valid/multiline-string.toml"), include_str!("valid/multiline-string.toml"),
include_str!("valid/multiline-string.json")); include_str!("valid/multiline-string.json")
test!(raw_multiline_string, );
test!(
raw_multiline_string,
include_str!("valid/raw-multiline-string.toml"), include_str!("valid/raw-multiline-string.toml"),
include_str!("valid/raw-multiline-string.json")); include_str!("valid/raw-multiline-string.json")
test!(raw_string, );
test!(
raw_string,
include_str!("valid/raw-string.toml"), include_str!("valid/raw-string.toml"),
include_str!("valid/raw-string.json")); include_str!("valid/raw-string.json")
test!(string_empty, );
test!(
string_empty,
include_str!("valid/string-empty.toml"), include_str!("valid/string-empty.toml"),
include_str!("valid/string-empty.json")); include_str!("valid/string-empty.json")
test!(string_escapes, );
test!(
string_escapes,
include_str!("valid/string-escapes.toml"), include_str!("valid/string-escapes.toml"),
include_str!("valid/string-escapes.json")); include_str!("valid/string-escapes.json")
test!(string_simple, );
test!(
string_simple,
include_str!("valid/string-simple.toml"), include_str!("valid/string-simple.toml"),
include_str!("valid/string-simple.json")); include_str!("valid/string-simple.json")
test!(string_with_pound, );
test!(
string_with_pound,
include_str!("valid/string-with-pound.toml"), include_str!("valid/string-with-pound.toml"),
include_str!("valid/string-with-pound.json")); include_str!("valid/string-with-pound.json")
test!(table_array_implicit, );
test!(
table_array_implicit,
include_str!("valid/table-array-implicit.toml"), include_str!("valid/table-array-implicit.toml"),
include_str!("valid/table-array-implicit.json")); include_str!("valid/table-array-implicit.json")
test!(table_array_many, );
test!(
table_array_many,
include_str!("valid/table-array-many.toml"), include_str!("valid/table-array-many.toml"),
include_str!("valid/table-array-many.json")); include_str!("valid/table-array-many.json")
test!(table_array_nest, );
test!(
table_array_nest,
include_str!("valid/table-array-nest.toml"), include_str!("valid/table-array-nest.toml"),
include_str!("valid/table-array-nest.json")); include_str!("valid/table-array-nest.json")
test!(table_array_one, );
test!(
table_array_one,
include_str!("valid/table-array-one.toml"), include_str!("valid/table-array-one.toml"),
include_str!("valid/table-array-one.json")); include_str!("valid/table-array-one.json")
test!(table_empty, );
test!(
table_empty,
include_str!("valid/table-empty.toml"), include_str!("valid/table-empty.toml"),
include_str!("valid/table-empty.json")); include_str!("valid/table-empty.json")
test!(table_sub_empty, );
test!(
table_sub_empty,
include_str!("valid/table-sub-empty.toml"), include_str!("valid/table-sub-empty.toml"),
include_str!("valid/table-sub-empty.json")); include_str!("valid/table-sub-empty.json")
test!(table_multi_empty, );
test!(
table_multi_empty,
include_str!("valid/table-multi-empty.toml"), include_str!("valid/table-multi-empty.toml"),
include_str!("valid/table-multi-empty.json")); include_str!("valid/table-multi-empty.json")
test!(table_whitespace, );
test!(
table_whitespace,
include_str!("valid/table-whitespace.toml"), include_str!("valid/table-whitespace.toml"),
include_str!("valid/table-whitespace.json")); include_str!("valid/table-whitespace.json")
test!(table_with_pound, );
test!(
table_with_pound,
include_str!("valid/table-with-pound.toml"), include_str!("valid/table-with-pound.toml"),
include_str!("valid/table-with-pound.json")); include_str!("valid/table-with-pound.json")
test!(unicode_escape, );
test!(
unicode_escape,
include_str!("valid/unicode-escape.toml"), include_str!("valid/unicode-escape.toml"),
include_str!("valid/unicode-escape.json")); include_str!("valid/unicode-escape.json")
test!(unicode_literal, );
test!(
unicode_literal,
include_str!("valid/unicode-literal.toml"), include_str!("valid/unicode-literal.toml"),
include_str!("valid/unicode-literal.json")); include_str!("valid/unicode-literal.json")
test!(hard_example, );
test!(
hard_example,
include_str!("valid/hard_example.toml"), include_str!("valid/hard_example.toml"),
include_str!("valid/hard_example.json")); include_str!("valid/hard_example.json")
test!(example2, );
test!(
example2,
include_str!("valid/example2.toml"), include_str!("valid/example2.toml"),
include_str!("valid/example2.json")); include_str!("valid/example2.json")
test!(example3, );
test!(
example3,
include_str!("valid/example-v0.3.0.toml"), include_str!("valid/example-v0.3.0.toml"),
include_str!("valid/example-v0.3.0.json")); include_str!("valid/example-v0.3.0.json")
test!(example4, );
test!(
example4,
include_str!("valid/example-v0.4.0.toml"), include_str!("valid/example-v0.4.0.toml"),
include_str!("valid/example-v0.4.0.json")); include_str!("valid/example-v0.4.0.json")
test!(example_bom, );
test!(
example_bom,
include_str!("valid/example-bom.toml"), include_str!("valid/example-bom.toml"),
include_str!("valid/example.json")); include_str!("valid/example.json")
);
test!(datetime_truncate, test!(
datetime_truncate,
include_str!("valid/datetime-truncate.toml"), include_str!("valid/datetime-truncate.toml"),
include_str!("valid/datetime-truncate.json")); include_str!("valid/datetime-truncate.json")
test!(key_quote_newline, );
test!(
key_quote_newline,
include_str!("valid/key-quote-newline.toml"), include_str!("valid/key-quote-newline.toml"),
include_str!("valid/key-quote-newline.json")); include_str!("valid/key-quote-newline.json")
test!(table_array_nest_no_keys, );
test!(
table_array_nest_no_keys,
include_str!("valid/table-array-nest-no-keys.toml"), include_str!("valid/table-array-nest-no-keys.toml"),
include_str!("valid/table-array-nest-no-keys.json")); include_str!("valid/table-array-nest-no-keys.json")
test!(dotted_keys, );
test!(
dotted_keys,
include_str!("valid/dotted-keys.toml"), include_str!("valid/dotted-keys.toml"),
include_str!("valid/dotted-keys.json")); include_str!("valid/dotted-keys.json")
);
test!(quote_surrounded_value, test!(
quote_surrounded_value,
include_str!("valid/quote-surrounded-value.toml"), include_str!("valid/quote-surrounded-value.toml"),
include_str!("valid/quote-surrounded-value.json")); include_str!("valid/quote-surrounded-value.json")
);