1 extern crate rustc_serialize;
2 extern crate toml;
3 
4 use std::collections::BTreeMap;
5 use rustc_serialize::json::Json;
6 
7 use toml::{Parser, Value};
8 use toml::Value::{Table, Integer, Float, Boolean, Datetime, Array};
9 
to_json(toml: Value) -> Json10 fn to_json(toml: Value) -> Json {
11     fn doit(s: &str, json: Json) -> Json {
12         let mut map = BTreeMap::new();
13         map.insert(format!("{}", "type"), Json::String(format!("{}", s)));
14         map.insert(format!("{}", "value"), json);
15         Json::Object(map)
16     }
17     match toml {
18         Value::String(s) => doit("string", Json::String(s)),
19         Integer(i) => doit("integer", Json::String(format!("{}", i))),
20         Float(f) => doit("float", Json::String({
21             let s = format!("{:.15}", f);
22             let s = format!("{}", s.trim_right_matches('0'));
23             if s.ends_with(".") {format!("{}0", s)} else {s}
24         })),
25         Boolean(b) => doit("bool", Json::String(format!("{}", b))),
26         Datetime(s) => doit("datetime", Json::String(s)),
27         Array(arr) => {
28             let is_table = match arr.first() {
29                 Some(&Table(..)) => true,
30                 _ => false,
31             };
32             let json = Json::Array(arr.into_iter().map(to_json).collect());
33             if is_table {json} else {doit("array", json)}
34         }
35         Table(table) => Json::Object(table.into_iter().map(|(k, v)| {
36             (k, to_json(v))
37         }).collect()),
38     }
39 }
40 
run(toml: &str, json: &str)41 fn run(toml: &str, json: &str) {
42     let mut p = Parser::new(toml);
43     let table = p.parse();
44     assert!(p.errors.len() == 0, "had_errors: {:?}",
45             p.errors.iter().map(|e| {
46                 (e.desc.clone(), &toml[e.lo - 5..e.hi + 5])
47             }).collect::<Vec<(String, &str)>>());
48     assert!(table.is_some());
49     let toml = Table(table.unwrap());
50     let toml_string = format!("{}", toml);
51 
52     let json = Json::from_str(json).unwrap();
53     let toml_json = to_json(toml.clone());
54     assert!(json == toml_json,
55             "expected\n{}\ngot\n{}\n",
56             json.pretty(),
57             toml_json.pretty());
58 
59     let table2 = Parser::new(&toml_string).parse().unwrap();
60     // floats are a little lossy
61     if table2.values().any(|v| v.as_float().is_some()) { return }
62     assert_eq!(toml, Table(table2));
63 }
64 
65 macro_rules! test( ($name:ident, $toml:expr, $json:expr) => (
66     #[test]
67     fn $name() { run($toml, $json); }
68 ) );
69 
70 test!(array_empty,
71        include_str!("valid/array-empty.toml"),
72        include_str!("valid/array-empty.json"));
73 test!(array_nospaces,
74        include_str!("valid/array-nospaces.toml"),
75        include_str!("valid/array-nospaces.json"));
76 test!(arrays_hetergeneous,
77        include_str!("valid/arrays-hetergeneous.toml"),
78        include_str!("valid/arrays-hetergeneous.json"));
79 test!(arrays,
80        include_str!("valid/arrays.toml"),
81        include_str!("valid/arrays.json"));
82 test!(arrays_nested,
83        include_str!("valid/arrays-nested.toml"),
84        include_str!("valid/arrays-nested.json"));
85 test!(empty,
86        include_str!("valid/empty.toml"),
87        include_str!("valid/empty.json"));
88 test!(bool,
89        include_str!("valid/bool.toml"),
90        include_str!("valid/bool.json"));
91 test!(datetime,
92        include_str!("valid/datetime.toml"),
93        include_str!("valid/datetime.json"));
94 test!(example,
95        include_str!("valid/example.toml"),
96        include_str!("valid/example.json"));
97 test!(float,
98        include_str!("valid/float.toml"),
99        include_str!("valid/float.json"));
100 test!(implicit_and_explicit_after,
101        include_str!("valid/implicit-and-explicit-after.toml"),
102        include_str!("valid/implicit-and-explicit-after.json"));
103 test!(implicit_and_explicit_before,
104        include_str!("valid/implicit-and-explicit-before.toml"),
105        include_str!("valid/implicit-and-explicit-before.json"));
106 test!(implicit_groups,
107        include_str!("valid/implicit-groups.toml"),
108        include_str!("valid/implicit-groups.json"));
109 test!(integer,
110        include_str!("valid/integer.toml"),
111        include_str!("valid/integer.json"));
112 test!(key_equals_nospace,
113        include_str!("valid/key-equals-nospace.toml"),
114        include_str!("valid/key-equals-nospace.json"));
115 test!(key_space,
116        include_str!("valid/key-space.toml"),
117        include_str!("valid/key-space.json"));
118 test!(key_special_chars,
119        include_str!("valid/key-special-chars.toml"),
120        include_str!("valid/key-special-chars.json"));
121 test!(key_with_pound,
122        include_str!("valid/key-with-pound.toml"),
123        include_str!("valid/key-with-pound.json"));
124 test!(long_float,
125        include_str!("valid/long-float.toml"),
126        include_str!("valid/long-float.json"));
127 test!(long_integer,
128        include_str!("valid/long-integer.toml"),
129        include_str!("valid/long-integer.json"));
130 test!(multiline_string,
131        include_str!("valid/multiline-string.toml"),
132        include_str!("valid/multiline-string.json"));
133 test!(raw_multiline_string,
134        include_str!("valid/raw-multiline-string.toml"),
135        include_str!("valid/raw-multiline-string.json"));
136 test!(raw_string,
137        include_str!("valid/raw-string.toml"),
138        include_str!("valid/raw-string.json"));
139 test!(string_empty,
140        include_str!("valid/string-empty.toml"),
141        include_str!("valid/string-empty.json"));
142 test!(string_escapes,
143        include_str!("valid/string-escapes.toml"),
144        include_str!("valid/string-escapes.json"));
145 test!(string_simple,
146        include_str!("valid/string-simple.toml"),
147        include_str!("valid/string-simple.json"));
148 test!(string_with_pound,
149        include_str!("valid/string-with-pound.toml"),
150        include_str!("valid/string-with-pound.json"));
151 test!(table_array_implicit,
152        include_str!("valid/table-array-implicit.toml"),
153        include_str!("valid/table-array-implicit.json"));
154 test!(table_array_many,
155        include_str!("valid/table-array-many.toml"),
156        include_str!("valid/table-array-many.json"));
157 test!(table_array_nest,
158        include_str!("valid/table-array-nest.toml"),
159        include_str!("valid/table-array-nest.json"));
160 test!(table_array_one,
161        include_str!("valid/table-array-one.toml"),
162        include_str!("valid/table-array-one.json"));
163 test!(table_empty,
164        include_str!("valid/table-empty.toml"),
165        include_str!("valid/table-empty.json"));
166 test!(table_sub_empty,
167        include_str!("valid/table-sub-empty.toml"),
168        include_str!("valid/table-sub-empty.json"));
169 test!(table_whitespace,
170        include_str!("valid/table-whitespace.toml"),
171        include_str!("valid/table-whitespace.json"));
172 test!(table_with_pound,
173        include_str!("valid/table-with-pound.toml"),
174        include_str!("valid/table-with-pound.json"));
175 test!(unicode_escape,
176        include_str!("valid/unicode-escape.toml"),
177        include_str!("valid/unicode-escape.json"));
178 test!(unicode_literal,
179        include_str!("valid/unicode-literal.toml"),
180        include_str!("valid/unicode-literal.json"));
181 test!(hard_example,
182        include_str!("valid/hard_example.toml"),
183        include_str!("valid/hard_example.json"));
184 test!(example2,
185        include_str!("valid/example2.toml"),
186        include_str!("valid/example2.json"));
187 test!(example3,
188        include_str!("valid/example-v0.3.0.toml"),
189        include_str!("valid/example-v0.3.0.json"));
190 test!(example4,
191        include_str!("valid/example-v0.4.0.toml"),
192        include_str!("valid/example-v0.4.0.json"));
193 test!(example_bom,
194        include_str!("valid/example-bom.toml"),
195        include_str!("valid/example.json"));
196