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,8 +57,9 @@ 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
sf4 = nan sf4 = nan

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,29 +11,31 @@ macro_rules! bad {
assert!(e.contains($msg), "error: {}", e); assert!(e.contains($msg), "error: {}", e);
} }
} }
}) }};
} }
#[test] #[test]
fn crlf() { fn crlf() {
"\ "\
[project]\r\n\ [project]\r\n\
\r\n\ \r\n\
name = \"splay\"\r\n\ name = \"splay\"\r\n\
version = \"0.1.0\"\r\n\ version = \"0.1.0\"\r\n\
authors = [\"alex@crichton.co\"]\r\n\ authors = [\"alex@crichton.co\"]\r\n\
\r\n\ \r\n\
[[lib]]\r\n\ [[lib]]\r\n\
\r\n\ \r\n\
path = \"lib.rs\"\r\n\ path = \"lib.rs\"\r\n\
name = \"splay\"\r\n\ name = \"splay\"\r\n\
description = \"\"\"\ description = \"\"\"\
A Rust implementation of a TAR file reader and writer. This library does not\r\n\ A Rust implementation of a TAR file reader and writer. This library does not\r\n\
currently handle compression, but it is abstract over all I/O readers and\r\n\ 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;
@ -496,7 +519,7 @@ fn empty_arrays2() {
Table(map! {}), Table(map! {}),
} }
equivalent!{ equivalent! {
Foo { a: Some(vec![]) }, Foo { a: Some(vec![]) },
Table(map! { a: Array(vec![]) }), Table(map! { a: Array(vec![]) }),
} }
@ -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")
);