]> git.proxmox.com Git - rustc.git/blob - src/vendor/toml/tests/serde.rs
New upstream version 1.17.0+dfsg1
[rustc.git] / src / vendor / toml / tests / serde.rs
1 extern crate serde;
2 extern crate toml;
3 #[macro_use]
4 extern crate serde_derive;
5
6 use std::collections::{BTreeMap, HashSet};
7 use serde::{Deserialize, Deserializer};
8
9 use toml::Value;
10 use toml::Value::{Table, Integer, Array, Float};
11
12 macro_rules! t {
13 ($e:expr) => (match $e {
14 Ok(t) => t,
15 Err(e) => panic!("{} failed with {}", stringify!($e), e),
16 })
17 }
18
19 macro_rules! equivalent {
20 ($literal:expr, $toml:expr,) => ({
21 let toml = $toml;
22 let literal = $literal;
23
24 // In/out of Value is equivalent
25 println!("try_from");
26 assert_eq!(t!(Value::try_from(literal.clone())), toml);
27 println!("try_into");
28 assert_eq!(literal, t!(toml.clone().try_into()));
29
30 // Through a string equivalent
31 println!("to_string(literal)");
32 assert_eq!(t!(toml::to_string(&literal)), toml.to_string());
33 println!("to_string(toml)");
34 assert_eq!(t!(toml::to_string(&toml)), toml.to_string());
35 println!("literal, from_str(toml)");
36 assert_eq!(literal, t!(toml::from_str(&toml.to_string())));
37 println!("toml, from_str(toml)");
38 assert_eq!(toml, t!(toml::from_str(&toml.to_string())));
39 })
40 }
41
42 macro_rules! error {
43 ($ty:ty, $toml:expr, $error:expr) => ({
44 println!("attempting parsing");
45 match toml::from_str::<$ty>(&$toml.to_string()) {
46 Ok(_) => panic!("successful"),
47 Err(e) => {
48 assert!(e.to_string().contains($error),
49 "bad error: {}", e);
50 }
51 }
52
53 println!("attempting toml decoding");
54 match $toml.try_into::<$ty>() {
55 Ok(_) => panic!("successful"),
56 Err(e) => {
57 assert!(e.to_string().contains($error),
58 "bad error: {}", e);
59 }
60 }
61 })
62 }
63
64 macro_rules! decode( ($t:expr) => ({
65 t!($t.try_into())
66 }) );
67
68 macro_rules! map( ($($k:ident: $v:expr),*) => ({
69 let mut _m = BTreeMap::new();
70 $(_m.insert(stringify!($k).to_string(), $v);)*
71 _m
72 }) );
73
74 #[test]
75 fn smoke() {
76 #[derive(Serialize, Deserialize, PartialEq, Debug, Clone)]
77 struct Foo { a: isize }
78
79 equivalent!(
80 Foo { a: 2 },
81 Table(map! { a: Integer(2) }),
82 );
83 }
84
85 #[test]
86 fn smoke_hyphen() {
87 #[derive(Serialize, Deserialize, PartialEq, Debug, Clone)]
88 struct Foo {
89 a_b: isize,
90 }
91
92 equivalent! {
93 Foo { a_b: 2 },
94 Table(map! { a_b: Integer(2) }),
95 }
96
97 #[derive(Serialize, Deserialize, PartialEq, Debug, Clone)]
98 struct Foo2 {
99 #[serde(rename = "a-b")]
100 a_b: isize,
101 }
102
103 let mut m = BTreeMap::new();
104 m.insert("a-b".to_string(), Integer(2));
105 equivalent! {
106 Foo2 { a_b: 2 },
107 Table(m),
108 }
109 }
110
111 #[test]
112 fn nested() {
113 #[derive(Serialize, Deserialize, PartialEq, Debug, Clone)]
114 struct Foo { a: isize, b: Bar }
115 #[derive(Serialize, Deserialize, PartialEq, Debug, Clone)]
116 struct Bar { a: String }
117
118 equivalent! {
119 Foo { a: 2, b: Bar { a: "test".to_string() } },
120 Table(map! {
121 a: Integer(2),
122 b: Table(map! {
123 a: Value::String("test".to_string())
124 })
125 }),
126 }
127 }
128
129 #[test]
130 fn application_decode_error() {
131 #[derive(PartialEq, Debug)]
132 struct Range10(usize);
133 impl Deserialize for Range10 {
134 fn deserialize<D: Deserializer>(d: D) -> Result<Range10, D::Error> {
135 let x: usize = try!(Deserialize::deserialize(d));
136 if x > 10 {
137 Err(serde::de::Error::custom("more than 10"))
138 } else {
139 Ok(Range10(x))
140 }
141 }
142 }
143 let d_good = Integer(5);
144 let d_bad1 = Value::String("not an isize".to_string());
145 let d_bad2 = Integer(11);
146
147 assert_eq!(Range10(5), d_good.try_into().unwrap());
148
149 let err1: Result<Range10, _> = d_bad1.try_into();
150 assert!(err1.is_err());
151 let err2: Result<Range10, _> = d_bad2.try_into();
152 assert!(err2.is_err());
153 }
154
155 #[test]
156 fn array() {
157 #[derive(Serialize, Deserialize, PartialEq, Debug, Clone)]
158 struct Foo { a: Vec<isize> }
159
160 equivalent! {
161 Foo { a: vec![1, 2, 3, 4] },
162 Table(map! {
163 a: Array(vec![
164 Integer(1),
165 Integer(2),
166 Integer(3),
167 Integer(4)
168 ])
169 }),
170 };
171 }
172
173 #[test]
174 fn inner_structs_with_options() {
175 #[derive(Serialize, Deserialize, PartialEq, Debug, Clone)]
176 struct Foo {
177 a: Option<Box<Foo>>,
178 b: Bar,
179 }
180 #[derive(Serialize, Deserialize, PartialEq, Debug, Clone)]
181 struct Bar {
182 a: String,
183 b: f64,
184 }
185
186 equivalent! {
187 Foo {
188 a: Some(Box::new(Foo {
189 a: None,
190 b: Bar { a: "foo".to_string(), b: 4.5 },
191 })),
192 b: Bar { a: "bar".to_string(), b: 1.0 },
193 },
194 Table(map! {
195 a: Table(map! {
196 b: Table(map! {
197 a: Value::String("foo".to_string()),
198 b: Float(4.5)
199 })
200 }),
201 b: Table(map! {
202 a: Value::String("bar".to_string()),
203 b: Float(1.0)
204 })
205 }),
206 }
207 }
208
209 #[test]
210 fn hashmap() {
211 #[derive(Serialize, Deserialize, PartialEq, Debug, Clone)]
212 struct Foo {
213 set: HashSet<char>,
214 map: BTreeMap<String, isize>,
215 }
216
217 equivalent! {
218 Foo {
219 map: {
220 let mut m = BTreeMap::new();
221 m.insert("foo".to_string(), 10);
222 m.insert("bar".to_string(), 4);
223 m
224 },
225 set: {
226 let mut s = HashSet::new();
227 s.insert('a');
228 s
229 },
230 },
231 Table(map! {
232 map: Table(map! {
233 foo: Integer(10),
234 bar: Integer(4)
235 }),
236 set: Array(vec![Value::String("a".to_string())])
237 }),
238 }
239 }
240
241 #[test]
242 fn table_array() {
243 #[derive(Serialize, Deserialize, PartialEq, Debug, Clone)]
244 struct Foo { a: Vec<Bar>, }
245 #[derive(Serialize, Deserialize, PartialEq, Debug, Clone)]
246 struct Bar { a: isize }
247
248 equivalent! {
249 Foo { a: vec![Bar { a: 1 }, Bar { a: 2 }] },
250 Table(map! {
251 a: Array(vec![
252 Table(map!{ a: Integer(1) }),
253 Table(map!{ a: Integer(2) }),
254 ])
255 }),
256 }
257 }
258
259 #[test]
260 fn type_errors() {
261 #[derive(Deserialize)]
262 #[allow(dead_code)]
263 struct Foo { bar: isize }
264
265 error! {
266 Foo,
267 Table(map! {
268 bar: Value::String("a".to_string())
269 }),
270 "invalid type: string \"a\", expected isize for key `bar`"
271 }
272
273 #[derive(Deserialize)]
274 #[allow(dead_code)]
275 struct Bar { foo: Foo }
276
277 error! {
278 Bar,
279 Table(map! {
280 foo: Table(map! {
281 bar: Value::String("a".to_string())
282 })
283 }),
284 "invalid type: string \"a\", expected isize for key `foo.bar`"
285 }
286 }
287
288 #[test]
289 fn missing_errors() {
290 #[derive(Serialize, Deserialize, PartialEq, Debug)]
291 struct Foo { bar: isize }
292
293 error! {
294 Foo,
295 Table(map! { }),
296 "missing field `bar`"
297 }
298 }
299
300 #[test]
301 fn parse_enum() {
302 #[derive(Serialize, Deserialize, PartialEq, Debug, Clone)]
303 struct Foo { a: E }
304 #[derive(Serialize, Deserialize, PartialEq, Debug, Clone)]
305 #[serde(untagged)]
306 enum E {
307 Bar(isize),
308 Baz(String),
309 Last(Foo2),
310 }
311 #[derive(Serialize, Deserialize, PartialEq, Debug, Clone)]
312 struct Foo2 {
313 test: String,
314 }
315
316 equivalent! {
317 Foo { a: E::Bar(10) },
318 Table(map! { a: Integer(10) }),
319 }
320
321 equivalent! {
322 Foo { a: E::Baz("foo".to_string()) },
323 Table(map! { a: Value::String("foo".to_string()) }),
324 }
325
326 equivalent! {
327 Foo { a: E::Last(Foo2 { test: "test".to_string() }) },
328 Table(map! { a: Table(map! { test: Value::String("test".to_string()) }) }),
329 }
330 }
331
332 // #[test]
333 // fn unused_fields() {
334 // #[derive(Serialize, Deserialize, PartialEq, Debug)]
335 // struct Foo { a: isize }
336 //
337 // let v = Foo { a: 2 };
338 // let mut d = Decoder::new(Table(map! {
339 // a, Integer(2),
340 // b, Integer(5)
341 // }));
342 // assert_eq!(v, t!(Deserialize::deserialize(&mut d)));
343 //
344 // assert_eq!(d.toml, Some(Table(map! {
345 // b, Integer(5)
346 // })));
347 // }
348 //
349 // #[test]
350 // fn unused_fields2() {
351 // #[derive(Serialize, Deserialize, PartialEq, Debug)]
352 // struct Foo { a: Bar }
353 // #[derive(Serialize, Deserialize, PartialEq, Debug)]
354 // struct Bar { a: isize }
355 //
356 // let v = Foo { a: Bar { a: 2 } };
357 // let mut d = Decoder::new(Table(map! {
358 // a, Table(map! {
359 // a, Integer(2),
360 // b, Integer(5)
361 // })
362 // }));
363 // assert_eq!(v, t!(Deserialize::deserialize(&mut d)));
364 //
365 // assert_eq!(d.toml, Some(Table(map! {
366 // a, Table(map! {
367 // b, Integer(5)
368 // })
369 // })));
370 // }
371 //
372 // #[test]
373 // fn unused_fields3() {
374 // #[derive(Serialize, Deserialize, PartialEq, Debug)]
375 // struct Foo { a: Bar }
376 // #[derive(Serialize, Deserialize, PartialEq, Debug)]
377 // struct Bar { a: isize }
378 //
379 // let v = Foo { a: Bar { a: 2 } };
380 // let mut d = Decoder::new(Table(map! {
381 // a, Table(map! {
382 // a, Integer(2)
383 // })
384 // }));
385 // assert_eq!(v, t!(Deserialize::deserialize(&mut d)));
386 //
387 // assert_eq!(d.toml, None);
388 // }
389 //
390 // #[test]
391 // fn unused_fields4() {
392 // #[derive(Serialize, Deserialize, PartialEq, Debug)]
393 // struct Foo { a: BTreeMap<String, String> }
394 //
395 // let v = Foo { a: map! { a, "foo".to_string() } };
396 // let mut d = Decoder::new(Table(map! {
397 // a, Table(map! {
398 // a, Value::String("foo".to_string())
399 // })
400 // }));
401 // assert_eq!(v, t!(Deserialize::deserialize(&mut d)));
402 //
403 // assert_eq!(d.toml, None);
404 // }
405 //
406 // #[test]
407 // fn unused_fields5() {
408 // #[derive(Serialize, Deserialize, PartialEq, Debug)]
409 // struct Foo { a: Vec<String> }
410 //
411 // let v = Foo { a: vec!["a".to_string()] };
412 // let mut d = Decoder::new(Table(map! {
413 // a, Array(vec![Value::String("a".to_string())])
414 // }));
415 // assert_eq!(v, t!(Deserialize::deserialize(&mut d)));
416 //
417 // assert_eq!(d.toml, None);
418 // }
419 //
420 // #[test]
421 // fn unused_fields6() {
422 // #[derive(Serialize, Deserialize, PartialEq, Debug)]
423 // struct Foo { a: Option<Vec<String>> }
424 //
425 // let v = Foo { a: Some(vec![]) };
426 // let mut d = Decoder::new(Table(map! {
427 // a, Array(vec![])
428 // }));
429 // assert_eq!(v, t!(Deserialize::deserialize(&mut d)));
430 //
431 // assert_eq!(d.toml, None);
432 // }
433 //
434 // #[test]
435 // fn unused_fields7() {
436 // #[derive(Serialize, Deserialize, PartialEq, Debug)]
437 // struct Foo { a: Vec<Bar> }
438 // #[derive(Serialize, Deserialize, PartialEq, Debug)]
439 // struct Bar { a: isize }
440 //
441 // let v = Foo { a: vec![Bar { a: 1 }] };
442 // let mut d = Decoder::new(Table(map! {
443 // a, Array(vec![Table(map! {
444 // a, Integer(1),
445 // b, Integer(2)
446 // })])
447 // }));
448 // assert_eq!(v, t!(Deserialize::deserialize(&mut d)));
449 //
450 // assert_eq!(d.toml, Some(Table(map! {
451 // a, Array(vec![Table(map! {
452 // b, Integer(2)
453 // })])
454 // })));
455 // }
456
457 #[test]
458 fn empty_arrays() {
459 #[derive(Serialize, Deserialize, PartialEq, Debug, Clone)]
460 struct Foo { a: Vec<Bar> }
461 #[derive(Serialize, Deserialize, PartialEq, Debug, Clone)]
462 struct Bar;
463
464 equivalent! {
465 Foo { a: vec![] },
466 Table(map! {a: Array(Vec::new())}),
467 }
468 }
469
470 #[test]
471 fn empty_arrays2() {
472 #[derive(Serialize, Deserialize, PartialEq, Debug, Clone)]
473 struct Foo { a: Option<Vec<Bar>> }
474 #[derive(Serialize, Deserialize, PartialEq, Debug, Clone)]
475 struct Bar;
476
477 equivalent! {
478 Foo { a: None },
479 Table(map! {}),
480 }
481
482 equivalent!{
483 Foo { a: Some(vec![]) },
484 Table(map! { a: Array(vec![]) }),
485 }
486 }
487
488 #[test]
489 fn extra_keys() {
490 #[derive(Serialize, Deserialize)]
491 struct Foo { a: isize }
492
493 let toml = Table(map! { a: Integer(2), b: Integer(2) });
494 assert!(toml.clone().try_into::<Foo>().is_ok());
495 assert!(toml::from_str::<Foo>(&toml.to_string()).is_ok());
496 }