2021-01-03 21:05:43 -06:00
|
|
|
#![allow(
|
|
|
|
clippy::cast_lossless,
|
Ignore derive_partial_eq_without_eq clippy lint
error: you are deriving `PartialEq` and can implement `Eq`
--> serde/src/de/value.rs:51:17
|
51 | #[derive(Clone, PartialEq)]
| ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq`
|
= note: `-D clippy::derive-partial-eq-without-eq` implied by `-D clippy::all`
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#derive_partial_eq_without_eq
error: you are deriving `PartialEq` and can implement `Eq`
--> serde_derive/src/internals/case.rs:13:23
|
13 | #[derive(Copy, Clone, PartialEq)]
| ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq`
|
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#derive_partial_eq_without_eq
error: you are deriving `PartialEq` and can implement `Eq`
--> test_suite/tests/unstable/mod.rs:6:21
|
6 | #[derive(Debug, PartialEq, Serialize, Deserialize)]
| ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq`
|
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#derive_partial_eq_without_eq
error: you are deriving `PartialEq` and can implement `Eq`
--> test_suite/tests/test_ignored_any.rs:7:10
|
7 | #[derive(PartialEq, Debug, Deserialize)]
| ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq`
|
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#derive_partial_eq_without_eq
error: you are deriving `PartialEq` and can implement `Eq`
--> test_suite/tests/test_identifier.rs:7:34
|
7 | #[derive(Deserialize, Debug, PartialEq)]
| ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq`
|
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#derive_partial_eq_without_eq
error: you are deriving `PartialEq` and can implement `Eq`
--> test_suite/tests/test_identifier.rs:24:34
|
24 | #[derive(Deserialize, Debug, PartialEq)]
| ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq`
|
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#derive_partial_eq_without_eq
error: you are deriving `PartialEq` and can implement `Eq`
--> test_suite/tests/test_identifier.rs:41:34
|
41 | #[derive(Deserialize, Debug, PartialEq)]
| ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq`
|
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#derive_partial_eq_without_eq
error: you are deriving `PartialEq` and can implement `Eq`
--> test_suite/tests/test_identifier.rs:59:34
|
59 | #[derive(Deserialize, Debug, PartialEq)]
| ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq`
|
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#derive_partial_eq_without_eq
error: you are deriving `PartialEq` and can implement `Eq`
--> test_suite/tests/test_ser.rs:46:10
|
46 | #[derive(PartialEq, Debug)]
| ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq`
|
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#derive_partial_eq_without_eq
error: you are deriving `PartialEq` and can implement `Eq`
--> test_suite/tests/test_value.rs:11:34
|
11 | #[derive(Deserialize, Debug, PartialEq)]
| ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq`
|
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#derive_partial_eq_without_eq
error: you are deriving `PartialEq` and can implement `Eq`
--> test_suite/tests/test_de_error.rs:15:23
|
15 | #[derive(Copy, Clone, PartialEq, Debug, Deserialize)]
| ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq`
|
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#derive_partial_eq_without_eq
error: you are deriving `PartialEq` and can implement `Eq`
--> test_suite/tests/test_de_error.rs:18:10
|
18 | #[derive(PartialEq, Debug, Deserialize)]
| ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq`
|
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#derive_partial_eq_without_eq
error: you are deriving `PartialEq` and can implement `Eq`
--> test_suite/tests/test_de_error.rs:26:10
|
26 | #[derive(PartialEq, Debug, Deserialize)]
| ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq`
|
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#derive_partial_eq_without_eq
error: you are deriving `PartialEq` and can implement `Eq`
--> test_suite/tests/test_de_error.rs:34:10
|
34 | #[derive(PartialEq, Debug, Deserialize)]
| ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq`
|
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#derive_partial_eq_without_eq
error: you are deriving `PartialEq` and can implement `Eq`
--> test_suite/tests/test_de_error.rs:41:19
|
41 | #[derive(Default, PartialEq, Debug)]
| ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq`
|
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#derive_partial_eq_without_eq
error: you are deriving `PartialEq` and can implement `Eq`
--> test_suite/tests/test_de_error.rs:60:10
|
60 | #[derive(PartialEq, Debug, Deserialize)]
| ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq`
|
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#derive_partial_eq_without_eq
error: you are deriving `PartialEq` and can implement `Eq`
--> test_suite/tests/test_borrow.rs:70:34
|
70 | #[derive(Deserialize, Debug, PartialEq)]
| ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq`
|
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#derive_partial_eq_without_eq
error: you are deriving `PartialEq` and can implement `Eq`
--> test_suite/tests/test_borrow.rs:97:34
|
97 | #[derive(Deserialize, Debug, PartialEq)]
| ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq`
|
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#derive_partial_eq_without_eq
error: you are deriving `PartialEq` and can implement `Eq`
--> test_suite/tests/test_borrow.rs:106:34
|
106 | #[derive(Deserialize, Debug, PartialEq)]
| ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq`
|
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#derive_partial_eq_without_eq
error: you are deriving `PartialEq` and can implement `Eq`
--> test_suite/tests/test_de.rs:43:23
|
43 | #[derive(Copy, Clone, PartialEq, Debug, Deserialize)]
| ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq`
|
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#derive_partial_eq_without_eq
error: you are deriving `PartialEq` and can implement `Eq`
--> test_suite/tests/test_de.rs:46:10
|
46 | #[derive(PartialEq, Debug, Deserialize)]
| ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq`
|
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#derive_partial_eq_without_eq
error: you are deriving `PartialEq` and can implement `Eq`
--> test_suite/tests/test_de.rs:49:10
|
49 | #[derive(PartialEq, Debug, Deserialize)]
| ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq`
|
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#derive_partial_eq_without_eq
error: you are deriving `PartialEq` and can implement `Eq`
--> test_suite/tests/test_de.rs:52:10
|
52 | #[derive(PartialEq, Debug, Deserialize)]
| ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq`
|
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#derive_partial_eq_without_eq
error: you are deriving `PartialEq` and can implement `Eq`
--> test_suite/tests/test_de.rs:76:10
|
76 | #[derive(PartialEq, Debug, Deserialize)]
| ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq`
|
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#derive_partial_eq_without_eq
error: you are deriving `PartialEq` and can implement `Eq`
--> test_suite/tests/test_de.rs:82:10
|
82 | #[derive(PartialEq, Debug, Deserialize)]
| ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq`
|
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#derive_partial_eq_without_eq
error: you are deriving `PartialEq` and can implement `Eq`
--> test_suite/tests/test_de.rs:102:10
|
102 | #[derive(PartialEq, Debug, Deserialize)]
| ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq`
|
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#derive_partial_eq_without_eq
error: you are deriving `PartialEq` and can implement `Eq`
--> test_suite/tests/test_de.rs:109:19
|
109 | #[derive(Default, PartialEq, Debug)]
| ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq`
|
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#derive_partial_eq_without_eq
error: you are deriving `PartialEq` and can implement `Eq`
--> test_suite/tests/test_de.rs:128:10
|
128 | #[derive(PartialEq, Debug, Deserialize)]
| ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq`
|
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#derive_partial_eq_without_eq
error: you are deriving `PartialEq` and can implement `Eq`
--> test_suite/tests/test_de.rs:135:10
|
135 | #[derive(PartialEq, Debug)]
| ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq`
|
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#derive_partial_eq_without_eq
error: you are deriving `PartialEq` and can implement `Eq`
--> test_suite/tests/test_de.rs:185:14
|
185 | #[derive(PartialEq, Debug, Deserialize)]
| ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq`
|
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#derive_partial_eq_without_eq
error: you are deriving `PartialEq` and can implement `Eq`
--> test_suite/tests/test_macros.rs:25:17
|
25 | #[derive(Debug, PartialEq, Serialize, Deserialize)]
| ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq`
|
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#derive_partial_eq_without_eq
error: you are deriving `PartialEq` and can implement `Eq`
--> test_suite/tests/test_macros.rs:110:17
|
110 | #[derive(Debug, PartialEq, Serialize, Deserialize)]
| ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq`
|
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#derive_partial_eq_without_eq
error: you are deriving `PartialEq` and can implement `Eq`
--> test_suite/tests/test_macros.rs:580:21
|
580 | #[derive(Debug, PartialEq, Serialize, Deserialize)]
| ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq`
|
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#derive_partial_eq_without_eq
error: you are deriving `PartialEq` and can implement `Eq`
--> test_suite/tests/test_macros.rs:607:21
|
607 | #[derive(Debug, PartialEq, Serialize, Deserialize)]
| ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq`
|
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#derive_partial_eq_without_eq
error: you are deriving `PartialEq` and can implement `Eq`
--> test_suite/tests/test_macros.rs:681:21
|
681 | #[derive(Debug, PartialEq, Serialize, Deserialize)]
| ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq`
|
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#derive_partial_eq_without_eq
error: you are deriving `PartialEq` and can implement `Eq`
--> test_suite/tests/test_macros.rs:684:21
|
684 | #[derive(Debug, PartialEq, Serialize, Deserialize)]
| ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq`
|
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#derive_partial_eq_without_eq
error: you are deriving `PartialEq` and can implement `Eq`
--> test_suite/tests/test_macros.rs:816:21
|
816 | #[derive(Debug, PartialEq, Deserialize)]
| ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq`
|
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#derive_partial_eq_without_eq
error: you are deriving `PartialEq` and can implement `Eq`
--> test_suite/tests/test_macros.rs:976:21
|
976 | #[derive(Debug, PartialEq, Serialize, Deserialize)]
| ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq`
|
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#derive_partial_eq_without_eq
error: you are deriving `PartialEq` and can implement `Eq`
--> test_suite/tests/test_macros.rs:1027:21
|
1027 | #[derive(Debug, PartialEq, Serialize, Deserialize)]
| ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq`
|
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#derive_partial_eq_without_eq
error: you are deriving `PartialEq` and can implement `Eq`
--> test_suite/tests/test_macros.rs:1273:21
|
1273 | #[derive(Debug, PartialEq, Deserialize)]
| ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq`
|
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#derive_partial_eq_without_eq
error: you are deriving `PartialEq` and can implement `Eq`
--> test_suite/tests/test_macros.rs:1342:21
|
1342 | #[derive(Debug, PartialEq, Serialize, Deserialize)]
| ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq`
|
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#derive_partial_eq_without_eq
error: you are deriving `PartialEq` and can implement `Eq`
--> test_suite/tests/test_macros.rs:1413:21
|
1413 | #[derive(Debug, PartialEq, Serialize, Deserialize)]
| ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq`
|
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#derive_partial_eq_without_eq
error: you are deriving `PartialEq` and can implement `Eq`
--> test_suite/tests/test_macros.rs:1450:21
|
1450 | #[derive(Debug, PartialEq, Serialize, Deserialize)]
| ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq`
|
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#derive_partial_eq_without_eq
error: you are deriving `PartialEq` and can implement `Eq`
--> test_suite/tests/test_macros.rs:1474:21
|
1474 | #[derive(Debug, PartialEq, Serialize, Deserialize)]
| ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq`
|
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#derive_partial_eq_without_eq
error: you are deriving `PartialEq` and can implement `Eq`
--> test_suite/tests/test_macros.rs:1509:21
|
1509 | #[derive(Debug, PartialEq, Serialize, Deserialize)]
| ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq`
|
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#derive_partial_eq_without_eq
error: you are deriving `PartialEq` and can implement `Eq`
--> test_suite/tests/test_macros.rs:1543:21
|
1543 | #[derive(Debug, PartialEq, Serialize, Deserialize)]
| ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq`
|
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#derive_partial_eq_without_eq
error: you are deriving `PartialEq` and can implement `Eq`
--> test_suite/tests/test_macros.rs:1601:21
|
1601 | #[derive(Debug, PartialEq, Deserialize)]
| ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq`
|
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#derive_partial_eq_without_eq
error: you are deriving `PartialEq` and can implement `Eq`
--> test_suite/tests/test_macros.rs:1743:45
|
1743 | #[derive(Serialize, Deserialize, Debug, PartialEq)]
| ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq`
|
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#derive_partial_eq_without_eq
error: you are deriving `PartialEq` and can implement `Eq`
--> test_suite/tests/test_macros.rs:1763:45
|
1763 | #[derive(Serialize, Deserialize, Debug, PartialEq)]
| ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq`
|
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#derive_partial_eq_without_eq
error: you are deriving `PartialEq` and can implement `Eq`
--> test_suite/tests/test_macros.rs:1770:45
|
1770 | #[derive(Serialize, Deserialize, Debug, PartialEq)]
| ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq`
|
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#derive_partial_eq_without_eq
error: you are deriving `PartialEq` and can implement `Eq`
--> test_suite/tests/test_macros.rs:1870:21
|
1870 | #[derive(Debug, PartialEq, Serialize, Deserialize)]
| ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq`
|
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#derive_partial_eq_without_eq
error: you are deriving `PartialEq` and can implement `Eq`
--> test_suite/tests/test_macros.rs:1888:21
|
1888 | #[derive(Debug, PartialEq, Serialize, Deserialize)]
| ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq`
|
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#derive_partial_eq_without_eq
error: you are deriving `PartialEq` and can implement `Eq`
--> test_suite/tests/test_annotations.rs:108:17
|
108 | #[derive(Debug, PartialEq, Serialize, Deserialize)]
| ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq`
|
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#derive_partial_eq_without_eq
error: you are deriving `PartialEq` and can implement `Eq`
--> test_suite/tests/test_annotations.rs:124:17
|
124 | #[derive(Debug, PartialEq, Serialize, Deserialize)]
| ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq`
|
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#derive_partial_eq_without_eq
error: you are deriving `PartialEq` and can implement `Eq`
--> test_suite/tests/test_annotations.rs:147:17
|
147 | #[derive(Debug, PartialEq, Serialize, Deserialize)]
| ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq`
|
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#derive_partial_eq_without_eq
error: you are deriving `PartialEq` and can implement `Eq`
--> test_suite/tests/test_annotations.rs:344:17
|
344 | #[derive(Debug, PartialEq, Deserialize)]
| ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq`
|
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#derive_partial_eq_without_eq
error: you are deriving `PartialEq` and can implement `Eq`
--> test_suite/tests/test_annotations.rs:394:17
|
394 | #[derive(Debug, PartialEq)]
| ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq`
|
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#derive_partial_eq_without_eq
error: you are deriving `PartialEq` and can implement `Eq`
--> test_suite/tests/test_annotations.rs:413:17
|
413 | #[derive(Debug, PartialEq)]
| ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq`
|
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#derive_partial_eq_without_eq
error: you are deriving `PartialEq` and can implement `Eq`
--> test_suite/tests/test_annotations.rs:458:17
|
458 | #[derive(Debug, PartialEq, Serialize, Deserialize)]
| ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq`
|
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#derive_partial_eq_without_eq
error: you are deriving `PartialEq` and can implement `Eq`
--> test_suite/tests/test_annotations.rs:512:17
|
512 | #[derive(Debug, PartialEq, Serialize, Deserialize)]
| ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq`
|
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#derive_partial_eq_without_eq
error: you are deriving `PartialEq` and can implement `Eq`
--> test_suite/tests/test_annotations.rs:520:17
|
520 | #[derive(Debug, PartialEq, Serialize, Deserialize)]
| ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq`
|
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#derive_partial_eq_without_eq
error: you are deriving `PartialEq` and can implement `Eq`
--> test_suite/tests/test_annotations.rs:528:17
|
528 | #[derive(Debug, PartialEq, Deserialize)]
| ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq`
|
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#derive_partial_eq_without_eq
error: you are deriving `PartialEq` and can implement `Eq`
--> test_suite/tests/test_annotations.rs:647:17
|
647 | #[derive(Debug, PartialEq, Serialize, Deserialize)]
| ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq`
|
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#derive_partial_eq_without_eq
error: you are deriving `PartialEq` and can implement `Eq`
--> test_suite/tests/test_gen.rs:835:17
|
835 | #[derive(Debug, PartialEq, Deserialize)]
| ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq`
|
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#derive_partial_eq_without_eq
error: you are deriving `PartialEq` and can implement `Eq`
--> test_suite/tests/test_annotations.rs:675:17
|
675 | #[derive(Debug, PartialEq, Deserialize)]
| ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq`
|
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#derive_partial_eq_without_eq
error: you are deriving `PartialEq` and can implement `Eq`
--> test_suite/tests/test_annotations.rs:1047:17
|
1047 | #[derive(Debug, PartialEq)]
| ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq`
|
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#derive_partial_eq_without_eq
error: you are deriving `PartialEq` and can implement `Eq`
--> test_suite/tests/test_annotations.rs:1050:17
|
1050 | #[derive(Debug, PartialEq)]
| ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq`
|
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#derive_partial_eq_without_eq
error: you are deriving `PartialEq` and can implement `Eq`
--> test_suite/tests/test_annotations.rs:1196:17
|
1196 | #[derive(Debug, PartialEq, Serialize, Deserialize)]
| ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq`
|
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#derive_partial_eq_without_eq
error: you are deriving `PartialEq` and can implement `Eq`
--> test_suite/tests/test_annotations.rs:1514:17
|
1514 | #[derive(Debug, PartialEq, Deserialize)]
| ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq`
|
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#derive_partial_eq_without_eq
error: you are deriving `PartialEq` and can implement `Eq`
--> test_suite/tests/test_annotations.rs:1548:41
|
1548 | #[derive(Clone, Serialize, Deserialize, PartialEq, Debug)]
| ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq`
|
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#derive_partial_eq_without_eq
error: you are deriving `PartialEq` and can implement `Eq`
--> test_suite/tests/test_annotations.rs:1566:41
|
1566 | #[derive(Clone, Serialize, Deserialize, PartialEq, Debug)]
| ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq`
|
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#derive_partial_eq_without_eq
error: you are deriving `PartialEq` and can implement `Eq`
--> test_suite/tests/test_annotations.rs:1600:30
|
1600 | #[derive(Clone, Deserialize, PartialEq, Debug)]
| ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq`
|
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#derive_partial_eq_without_eq
error: you are deriving `PartialEq` and can implement `Eq`
--> test_suite/tests/test_annotations.rs:1803:21
|
1803 | #[derive(Debug, PartialEq, Serialize, Deserialize)]
| ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq`
|
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#derive_partial_eq_without_eq
error: you are deriving `PartialEq` and can implement `Eq`
--> test_suite/tests/test_annotations.rs:1843:21
|
1843 | #[derive(Debug, PartialEq, Serialize, Deserialize)]
| ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq`
|
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#derive_partial_eq_without_eq
error: you are deriving `PartialEq` and can implement `Eq`
--> test_suite/tests/test_annotations.rs:1852:21
|
1852 | #[derive(Debug, PartialEq, Serialize, Deserialize)]
| ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq`
|
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#derive_partial_eq_without_eq
error: you are deriving `PartialEq` and can implement `Eq`
--> test_suite/tests/test_annotations.rs:1947:21
|
1947 | #[derive(Debug, PartialEq, Deserialize)]
| ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq`
|
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#derive_partial_eq_without_eq
error: you are deriving `PartialEq` and can implement `Eq`
--> test_suite/tests/test_annotations.rs:2003:21
|
2003 | #[derive(Debug, PartialEq, Serialize, Deserialize)]
| ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq`
|
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#derive_partial_eq_without_eq
error: you are deriving `PartialEq` and can implement `Eq`
--> test_suite/tests/test_annotations.rs:2037:21
|
2037 | #[derive(Debug, PartialEq, Serialize, Deserialize)]
| ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq`
|
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#derive_partial_eq_without_eq
error: you are deriving `PartialEq` and can implement `Eq`
--> test_suite/tests/test_annotations.rs:2074:45
|
2074 | #[derive(Deserialize, Serialize, Debug, PartialEq)]
| ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq`
|
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#derive_partial_eq_without_eq
error: you are deriving `PartialEq` and can implement `Eq`
--> test_suite/tests/test_annotations.rs:2080:45
|
2080 | #[derive(Deserialize, Serialize, Debug, PartialEq)]
| ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq`
|
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#derive_partial_eq_without_eq
error: you are deriving `PartialEq` and can implement `Eq`
--> test_suite/tests/test_annotations.rs:2157:38
|
2157 | #[derive(Serialize, Deserialize, PartialEq, Debug)]
| ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq`
|
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#derive_partial_eq_without_eq
error: you are deriving `PartialEq` and can implement `Eq`
--> test_suite/tests/test_annotations.rs:2193:38
|
2193 | #[derive(Serialize, Deserialize, PartialEq, Debug)]
| ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq`
|
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#derive_partial_eq_without_eq
error: you are deriving `PartialEq` and can implement `Eq`
--> test_suite/tests/test_annotations.rs:2200:38
|
2200 | #[derive(Serialize, Deserialize, PartialEq, Debug)]
| ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq`
|
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#derive_partial_eq_without_eq
error: you are deriving `PartialEq` and can implement `Eq`
--> test_suite/tests/test_annotations.rs:2240:38
|
2240 | #[derive(Serialize, Deserialize, PartialEq, Debug)]
| ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq`
|
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#derive_partial_eq_without_eq
error: you are deriving `PartialEq` and can implement `Eq`
--> test_suite/tests/test_annotations.rs:2279:38
|
2279 | #[derive(Serialize, Deserialize, PartialEq, Debug)]
| ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq`
|
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#derive_partial_eq_without_eq
error: you are deriving `PartialEq` and can implement `Eq`
--> test_suite/tests/test_annotations.rs:2316:38
|
2316 | #[derive(Serialize, Deserialize, PartialEq, Debug)]
| ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq`
|
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#derive_partial_eq_without_eq
error: you are deriving `PartialEq` and can implement `Eq`
--> test_suite/tests/test_annotations.rs:2359:38
|
2359 | #[derive(Serialize, Deserialize, PartialEq, Debug)]
| ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq`
|
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#derive_partial_eq_without_eq
error: you are deriving `PartialEq` and can implement `Eq`
--> test_suite/tests/test_annotations.rs:2390:38
|
2390 | #[derive(Serialize, Deserialize, PartialEq, Debug)]
| ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq`
|
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#derive_partial_eq_without_eq
error: you are deriving `PartialEq` and can implement `Eq`
--> test_suite/tests/test_annotations.rs:2421:38
|
2421 | #[derive(Serialize, Deserialize, PartialEq, Debug)]
| ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq`
|
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#derive_partial_eq_without_eq
error: you are deriving `PartialEq` and can implement `Eq`
--> test_suite/tests/test_annotations.rs:2426:38
|
2426 | #[derive(Serialize, Deserialize, PartialEq, Debug)]
| ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq`
|
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#derive_partial_eq_without_eq
error: you are deriving `PartialEq` and can implement `Eq`
--> test_suite/tests/test_annotations.rs:2483:38
|
2483 | #[derive(Serialize, Deserialize, PartialEq, Debug)]
| ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq`
|
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#derive_partial_eq_without_eq
error: you are deriving `PartialEq` and can implement `Eq`
--> test_suite/tests/test_annotations.rs:2507:38
|
2507 | #[derive(Serialize, Deserialize, PartialEq, Debug)]
| ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq`
|
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#derive_partial_eq_without_eq
error: you are deriving `PartialEq` and can implement `Eq`
--> test_suite/tests/test_annotations.rs:2521:27
|
2521 | #[derive(Deserialize, PartialEq, Debug)]
| ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq`
|
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#derive_partial_eq_without_eq
error: you are deriving `PartialEq` and can implement `Eq`
--> test_suite/tests/test_annotations.rs:2552:27
|
2552 | #[derive(Deserialize, PartialEq, Debug)]
| ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq`
|
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#derive_partial_eq_without_eq
error: you are deriving `PartialEq` and can implement `Eq`
--> test_suite/tests/test_annotations.rs:2558:27
|
2558 | #[derive(Deserialize, PartialEq, Debug)]
| ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq`
|
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#derive_partial_eq_without_eq
error: you are deriving `PartialEq` and can implement `Eq`
--> test_suite/tests/test_annotations.rs:2586:14
|
2586 | #[derive(PartialEq, Debug)]
| ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq`
|
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#derive_partial_eq_without_eq
error: you are deriving `PartialEq` and can implement `Eq`
--> test_suite/tests/test_annotations.rs:2624:27
|
2624 | #[derive(Deserialize, PartialEq, Debug)]
| ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq`
|
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#derive_partial_eq_without_eq
error: you are deriving `PartialEq` and can implement `Eq`
--> test_suite/tests/test_annotations.rs:2647:27
|
2647 | #[derive(Deserialize, PartialEq, Debug)]
| ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq`
|
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#derive_partial_eq_without_eq
2022-05-21 22:36:25 -05:00
|
|
|
clippy::derive_partial_eq_without_eq,
|
2021-01-03 21:05:43 -06:00
|
|
|
clippy::from_over_into,
|
Ignore buggy nonstandard_macro_braces clippy lint
Clippy bug: https://github.com/rust-lang/rust-clippy/issues/7422
error: use of irregular braces for `format_args!` macro
--> test_suite/tests/test_gen.rs:528:25
|
528 | #[derive(Serialize, Deserialize)]
| ^^^^^^^^^^^
|
= note: `-D clippy::nonstandard-macro-braces` implied by `-D clippy::all`
help: consider writing `Deserialize`
--> test_suite/tests/test_gen.rs:528:25
|
528 | #[derive(Serialize, Deserialize)]
| ^^^^^^^^^^^
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#nonstandard_macro_braces
= note: this error originates in the derive macro `Deserialize` (in Nightly builds, run with -Z macro-backtrace for more info)
error: use of irregular braces for `format_args!` macro
--> test_suite/tests/test_annotations.rs:1791:43
|
1791 | #[derive(Debug, PartialEq, Serialize, Deserialize)]
| ^^^^^^^^^^^
|
= note: `-D clippy::nonstandard-macro-braces` implied by `-D clippy::all`
help: consider writing `Deserialize`
--> test_suite/tests/test_annotations.rs:1791:43
|
1791 | #[derive(Debug, PartialEq, Serialize, Deserialize)]
| ^^^^^^^^^^^
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#nonstandard_macro_braces
= note: this error originates in the derive macro `Deserialize` (in Nightly builds, run with -Z macro-backtrace for more info)
2021-07-02 22:57:57 -05:00
|
|
|
// Clippy bug: https://github.com/rust-lang/rust-clippy/issues/7422
|
|
|
|
clippy::nonstandard_macro_braces,
|
2021-11-04 22:21:43 -05:00
|
|
|
clippy::too_many_lines,
|
2022-04-30 23:30:38 -05:00
|
|
|
clippy::trivially_copy_pass_by_ref,
|
2023-02-02 13:04:18 -06:00
|
|
|
clippy::type_repetition_in_bounds,
|
|
|
|
clippy::uninlined_format_args,
|
2021-01-03 21:05:43 -06:00
|
|
|
)]
|
2017-09-09 13:08:19 -05:00
|
|
|
|
2023-04-29 15:18:42 -05:00
|
|
|
use serde::de::{self, IgnoredAny, MapAccess, Unexpected, Visitor};
|
2018-12-31 20:44:24 -06:00
|
|
|
use serde::{Deserialize, Deserializer, Serialize, Serializer};
|
2018-09-08 18:53:03 -05:00
|
|
|
|
2018-06-01 14:00:35 -05:00
|
|
|
use std::collections::{BTreeMap, HashMap};
|
2019-05-12 01:26:42 -05:00
|
|
|
use std::convert::TryFrom;
|
2019-07-17 14:27:26 -05:00
|
|
|
use std::fmt;
|
2018-05-20 15:53:29 -05:00
|
|
|
use std::marker::PhantomData;
|
2016-02-15 19:39:46 -06:00
|
|
|
|
2018-12-31 20:44:24 -06:00
|
|
|
use serde_test::{
|
2018-05-05 02:56:12 -05:00
|
|
|
assert_de_tokens, assert_de_tokens_error, assert_ser_tokens, assert_ser_tokens_error,
|
|
|
|
assert_tokens, Token,
|
|
|
|
};
|
2015-04-02 00:14:28 -05:00
|
|
|
|
feat(codegen): Inhibit generic bounds if skip_serializing
The generated code for a struct like:
struct Test<A, B, C> {
a: X<A>
#[serde(skip_serializing)]
b: B
#[serde(serialize_with="...")]
c: C
}
Used to be:
impl<A, B, C> Serialize for Test<A, B, C>
where A: Serialize,
B: Serialize,
C: Serialize,
{ ... }
Now it is:
impl<A, B, C> Serialize for Test<A, B, C>
where X<A>: Serialize,
{ ... }
Both `skip_serializing` and `serialize_with` mean the type does not need to
implement `Serialize`.
2016-02-28 14:17:29 -06:00
|
|
|
trait MyDefault: Sized {
|
2016-02-12 23:53:35 -06:00
|
|
|
fn my_default() -> Self;
|
feat(codegen): Inhibit generic bounds if skip_serializing
The generated code for a struct like:
struct Test<A, B, C> {
a: X<A>
#[serde(skip_serializing)]
b: B
#[serde(serialize_with="...")]
c: C
}
Used to be:
impl<A, B, C> Serialize for Test<A, B, C>
where A: Serialize,
B: Serialize,
C: Serialize,
{ ... }
Now it is:
impl<A, B, C> Serialize for Test<A, B, C>
where X<A>: Serialize,
{ ... }
Both `skip_serializing` and `serialize_with` mean the type does not need to
implement `Serialize`.
2016-02-28 14:17:29 -06:00
|
|
|
}
|
2016-02-13 00:05:02 -06:00
|
|
|
|
feat(codegen): Inhibit generic bounds if skip_serializing
The generated code for a struct like:
struct Test<A, B, C> {
a: X<A>
#[serde(skip_serializing)]
b: B
#[serde(serialize_with="...")]
c: C
}
Used to be:
impl<A, B, C> Serialize for Test<A, B, C>
where A: Serialize,
B: Serialize,
C: Serialize,
{ ... }
Now it is:
impl<A, B, C> Serialize for Test<A, B, C>
where X<A>: Serialize,
{ ... }
Both `skip_serializing` and `serialize_with` mean the type does not need to
implement `Serialize`.
2016-02-28 14:17:29 -06:00
|
|
|
trait ShouldSkip: Sized {
|
2016-02-13 00:05:02 -06:00
|
|
|
fn should_skip(&self) -> bool;
|
feat(codegen): Inhibit generic bounds if skip_serializing
The generated code for a struct like:
struct Test<A, B, C> {
a: X<A>
#[serde(skip_serializing)]
b: B
#[serde(serialize_with="...")]
c: C
}
Used to be:
impl<A, B, C> Serialize for Test<A, B, C>
where A: Serialize,
B: Serialize,
C: Serialize,
{ ... }
Now it is:
impl<A, B, C> Serialize for Test<A, B, C>
where X<A>: Serialize,
{ ... }
Both `skip_serializing` and `serialize_with` mean the type does not need to
implement `Serialize`.
2016-02-28 14:17:29 -06:00
|
|
|
}
|
2016-02-15 19:39:46 -06:00
|
|
|
|
feat(codegen): Inhibit generic bounds if skip_serializing
The generated code for a struct like:
struct Test<A, B, C> {
a: X<A>
#[serde(skip_serializing)]
b: B
#[serde(serialize_with="...")]
c: C
}
Used to be:
impl<A, B, C> Serialize for Test<A, B, C>
where A: Serialize,
B: Serialize,
C: Serialize,
{ ... }
Now it is:
impl<A, B, C> Serialize for Test<A, B, C>
where X<A>: Serialize,
{ ... }
Both `skip_serializing` and `serialize_with` mean the type does not need to
implement `Serialize`.
2016-02-28 14:17:29 -06:00
|
|
|
trait SerializeWith: Sized {
|
2017-01-14 18:07:43 -06:00
|
|
|
fn serialize_with<S>(&self, ser: S) -> Result<S::Ok, S::Error>
|
2017-04-13 14:28:23 -05:00
|
|
|
where
|
|
|
|
S: Serializer;
|
feat(codegen): Inhibit generic bounds if skip_serializing
The generated code for a struct like:
struct Test<A, B, C> {
a: X<A>
#[serde(skip_serializing)]
b: B
#[serde(serialize_with="...")]
c: C
}
Used to be:
impl<A, B, C> Serialize for Test<A, B, C>
where A: Serialize,
B: Serialize,
C: Serialize,
{ ... }
Now it is:
impl<A, B, C> Serialize for Test<A, B, C>
where X<A>: Serialize,
{ ... }
Both `skip_serializing` and `serialize_with` mean the type does not need to
implement `Serialize`.
2016-02-28 14:17:29 -06:00
|
|
|
}
|
2016-02-15 22:43:11 -06:00
|
|
|
|
feat(codegen): Inhibit generic bounds if skip_serializing
The generated code for a struct like:
struct Test<A, B, C> {
a: X<A>
#[serde(skip_serializing)]
b: B
#[serde(serialize_with="...")]
c: C
}
Used to be:
impl<A, B, C> Serialize for Test<A, B, C>
where A: Serialize,
B: Serialize,
C: Serialize,
{ ... }
Now it is:
impl<A, B, C> Serialize for Test<A, B, C>
where X<A>: Serialize,
{ ... }
Both `skip_serializing` and `serialize_with` mean the type does not need to
implement `Serialize`.
2016-02-28 14:17:29 -06:00
|
|
|
trait DeserializeWith: Sized {
|
2017-03-27 00:56:58 -05:00
|
|
|
fn deserialize_with<'de, D>(de: D) -> Result<Self, D::Error>
|
2017-04-13 14:28:23 -05:00
|
|
|
where
|
|
|
|
D: Deserializer<'de>;
|
2016-02-12 23:53:35 -06:00
|
|
|
}
|
|
|
|
|
feat(codegen): Inhibit generic bounds if skip_serializing
The generated code for a struct like:
struct Test<A, B, C> {
a: X<A>
#[serde(skip_serializing)]
b: B
#[serde(serialize_with="...")]
c: C
}
Used to be:
impl<A, B, C> Serialize for Test<A, B, C>
where A: Serialize,
B: Serialize,
C: Serialize,
{ ... }
Now it is:
impl<A, B, C> Serialize for Test<A, B, C>
where X<A>: Serialize,
{ ... }
Both `skip_serializing` and `serialize_with` mean the type does not need to
implement `Serialize`.
2016-02-28 14:17:29 -06:00
|
|
|
impl MyDefault for i32 {
|
2017-04-13 14:28:23 -05:00
|
|
|
fn my_default() -> Self {
|
|
|
|
123
|
|
|
|
}
|
feat(codegen): Inhibit generic bounds if skip_serializing
The generated code for a struct like:
struct Test<A, B, C> {
a: X<A>
#[serde(skip_serializing)]
b: B
#[serde(serialize_with="...")]
c: C
}
Used to be:
impl<A, B, C> Serialize for Test<A, B, C>
where A: Serialize,
B: Serialize,
C: Serialize,
{ ... }
Now it is:
impl<A, B, C> Serialize for Test<A, B, C>
where X<A>: Serialize,
{ ... }
Both `skip_serializing` and `serialize_with` mean the type does not need to
implement `Serialize`.
2016-02-28 14:17:29 -06:00
|
|
|
}
|
2016-02-13 00:05:02 -06:00
|
|
|
|
feat(codegen): Inhibit generic bounds if skip_serializing
The generated code for a struct like:
struct Test<A, B, C> {
a: X<A>
#[serde(skip_serializing)]
b: B
#[serde(serialize_with="...")]
c: C
}
Used to be:
impl<A, B, C> Serialize for Test<A, B, C>
where A: Serialize,
B: Serialize,
C: Serialize,
{ ... }
Now it is:
impl<A, B, C> Serialize for Test<A, B, C>
where X<A>: Serialize,
{ ... }
Both `skip_serializing` and `serialize_with` mean the type does not need to
implement `Serialize`.
2016-02-28 14:17:29 -06:00
|
|
|
impl ShouldSkip for i32 {
|
2017-04-13 14:28:23 -05:00
|
|
|
fn should_skip(&self) -> bool {
|
|
|
|
*self == 123
|
|
|
|
}
|
feat(codegen): Inhibit generic bounds if skip_serializing
The generated code for a struct like:
struct Test<A, B, C> {
a: X<A>
#[serde(skip_serializing)]
b: B
#[serde(serialize_with="...")]
c: C
}
Used to be:
impl<A, B, C> Serialize for Test<A, B, C>
where A: Serialize,
B: Serialize,
C: Serialize,
{ ... }
Now it is:
impl<A, B, C> Serialize for Test<A, B, C>
where X<A>: Serialize,
{ ... }
Both `skip_serializing` and `serialize_with` mean the type does not need to
implement `Serialize`.
2016-02-28 14:17:29 -06:00
|
|
|
}
|
2016-02-15 19:39:46 -06:00
|
|
|
|
feat(codegen): Inhibit generic bounds if skip_serializing
The generated code for a struct like:
struct Test<A, B, C> {
a: X<A>
#[serde(skip_serializing)]
b: B
#[serde(serialize_with="...")]
c: C
}
Used to be:
impl<A, B, C> Serialize for Test<A, B, C>
where A: Serialize,
B: Serialize,
C: Serialize,
{ ... }
Now it is:
impl<A, B, C> Serialize for Test<A, B, C>
where X<A>: Serialize,
{ ... }
Both `skip_serializing` and `serialize_with` mean the type does not need to
implement `Serialize`.
2016-02-28 14:17:29 -06:00
|
|
|
impl SerializeWith for i32 {
|
2017-01-14 18:07:43 -06:00
|
|
|
fn serialize_with<S>(&self, ser: S) -> Result<S::Ok, S::Error>
|
2017-04-13 14:28:23 -05:00
|
|
|
where
|
|
|
|
S: Serializer,
|
2016-02-15 19:39:46 -06:00
|
|
|
{
|
|
|
|
if *self == 123 {
|
|
|
|
true.serialize(ser)
|
|
|
|
} else {
|
|
|
|
false.serialize(ser)
|
|
|
|
}
|
|
|
|
}
|
feat(codegen): Inhibit generic bounds if skip_serializing
The generated code for a struct like:
struct Test<A, B, C> {
a: X<A>
#[serde(skip_serializing)]
b: B
#[serde(serialize_with="...")]
c: C
}
Used to be:
impl<A, B, C> Serialize for Test<A, B, C>
where A: Serialize,
B: Serialize,
C: Serialize,
{ ... }
Now it is:
impl<A, B, C> Serialize for Test<A, B, C>
where X<A>: Serialize,
{ ... }
Both `skip_serializing` and `serialize_with` mean the type does not need to
implement `Serialize`.
2016-02-28 14:17:29 -06:00
|
|
|
}
|
2016-02-15 22:43:11 -06:00
|
|
|
|
feat(codegen): Inhibit generic bounds if skip_serializing
The generated code for a struct like:
struct Test<A, B, C> {
a: X<A>
#[serde(skip_serializing)]
b: B
#[serde(serialize_with="...")]
c: C
}
Used to be:
impl<A, B, C> Serialize for Test<A, B, C>
where A: Serialize,
B: Serialize,
C: Serialize,
{ ... }
Now it is:
impl<A, B, C> Serialize for Test<A, B, C>
where X<A>: Serialize,
{ ... }
Both `skip_serializing` and `serialize_with` mean the type does not need to
implement `Serialize`.
2016-02-28 14:17:29 -06:00
|
|
|
impl DeserializeWith for i32 {
|
2017-03-27 00:56:58 -05:00
|
|
|
fn deserialize_with<'de, D>(de: D) -> Result<Self, D::Error>
|
2017-04-13 14:28:23 -05:00
|
|
|
where
|
|
|
|
D: Deserializer<'de>,
|
2016-02-15 22:43:11 -06:00
|
|
|
{
|
2018-12-31 20:46:14 -06:00
|
|
|
if Deserialize::deserialize(de)? {
|
2016-02-15 22:43:11 -06:00
|
|
|
Ok(123)
|
|
|
|
} else {
|
|
|
|
Ok(2)
|
|
|
|
}
|
|
|
|
}
|
2016-02-12 23:53:35 -06:00
|
|
|
}
|
|
|
|
|
2015-04-02 00:14:28 -05:00
|
|
|
#[derive(Debug, PartialEq, Serialize, Deserialize)]
|
2016-04-13 02:34:29 -05:00
|
|
|
struct DefaultStruct<A, B, C, D, E>
|
2017-04-13 14:28:23 -05:00
|
|
|
where
|
|
|
|
C: MyDefault,
|
|
|
|
E: MyDefault,
|
2016-04-13 01:42:24 -05:00
|
|
|
{
|
2016-02-12 23:53:35 -06:00
|
|
|
a1: A,
|
2017-12-23 22:24:57 -06:00
|
|
|
#[serde(default)]
|
|
|
|
a2: B,
|
|
|
|
#[serde(default = "MyDefault::my_default")]
|
|
|
|
a3: C,
|
|
|
|
#[serde(skip_deserializing)]
|
|
|
|
a4: D,
|
|
|
|
#[serde(skip_deserializing, default = "MyDefault::my_default")]
|
|
|
|
a5: E,
|
2016-02-12 23:53:35 -06:00
|
|
|
}
|
|
|
|
|
2018-12-10 23:47:56 -06:00
|
|
|
#[derive(Debug, PartialEq, Serialize, Deserialize)]
|
|
|
|
struct DefaultTupleStruct<A, B, C>(
|
|
|
|
A,
|
2018-12-11 00:09:02 -06:00
|
|
|
#[serde(default)] B,
|
|
|
|
#[serde(default = "MyDefault::my_default")] C,
|
2018-12-10 23:47:56 -06:00
|
|
|
)
|
|
|
|
where
|
|
|
|
C: MyDefault;
|
|
|
|
|
2018-03-14 12:46:47 -05:00
|
|
|
#[derive(Debug, PartialEq, Serialize, Deserialize)]
|
|
|
|
struct CollectOther {
|
|
|
|
a: u32,
|
|
|
|
b: u32,
|
2018-03-15 19:26:57 -05:00
|
|
|
#[serde(flatten)]
|
2018-03-14 12:46:47 -05:00
|
|
|
extra: HashMap<String, u32>,
|
|
|
|
}
|
|
|
|
|
2018-03-16 16:40:08 -05:00
|
|
|
#[derive(Debug, PartialEq, Serialize, Deserialize)]
|
2018-03-16 16:58:16 -05:00
|
|
|
struct FlattenStructEnumWrapper {
|
2018-03-16 16:40:08 -05:00
|
|
|
#[serde(flatten)]
|
2018-03-16 16:58:16 -05:00
|
|
|
data: FlattenStructEnum,
|
2018-03-16 16:40:08 -05:00
|
|
|
#[serde(flatten)]
|
|
|
|
extra: HashMap<String, String>,
|
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Debug, PartialEq, Serialize, Deserialize)]
|
|
|
|
#[serde(rename_all = "snake_case")]
|
2018-03-16 16:58:16 -05:00
|
|
|
enum FlattenStructEnum {
|
2018-04-30 03:41:22 -05:00
|
|
|
InsertInteger { index: u32, value: u32 },
|
2018-03-16 16:58:16 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Debug, PartialEq, Serialize, Deserialize)]
|
|
|
|
struct FlattenStructTagContentEnumWrapper {
|
|
|
|
outer: u32,
|
|
|
|
#[serde(flatten)]
|
2018-03-18 07:02:00 -05:00
|
|
|
data: FlattenStructTagContentEnumNewtype,
|
2018-03-16 16:58:16 -05:00
|
|
|
}
|
|
|
|
|
2018-03-18 07:02:00 -05:00
|
|
|
#[derive(Debug, PartialEq, Serialize, Deserialize)]
|
|
|
|
struct FlattenStructTagContentEnumNewtype(pub FlattenStructTagContentEnum);
|
|
|
|
|
2018-03-16 16:58:16 -05:00
|
|
|
#[derive(Debug, PartialEq, Serialize, Deserialize)]
|
|
|
|
#[serde(rename_all = "snake_case", tag = "type", content = "value")]
|
|
|
|
enum FlattenStructTagContentEnum {
|
2018-04-30 03:41:22 -05:00
|
|
|
InsertInteger { index: u32, value: u32 },
|
2018-03-18 07:10:54 -05:00
|
|
|
NewtypeVariant(FlattenStructTagContentEnumNewtypeVariant),
|
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Debug, PartialEq, Serialize, Deserialize)]
|
|
|
|
struct FlattenStructTagContentEnumNewtypeVariant {
|
|
|
|
value: u32,
|
2018-03-16 16:40:08 -05:00
|
|
|
}
|
|
|
|
|
2016-02-12 23:53:35 -06:00
|
|
|
#[test]
|
|
|
|
fn test_default_struct() {
|
|
|
|
assert_de_tokens(
|
2017-04-13 14:28:23 -05:00
|
|
|
&DefaultStruct {
|
2017-12-23 22:13:08 -06:00
|
|
|
a1: 1,
|
|
|
|
a2: 2,
|
|
|
|
a3: 3,
|
|
|
|
a4: 0,
|
|
|
|
a5: 123,
|
|
|
|
},
|
2016-06-29 01:50:19 -05:00
|
|
|
&[
|
2017-12-23 22:13:08 -06:00
|
|
|
Token::Struct {
|
|
|
|
name: "DefaultStruct",
|
|
|
|
len: 3,
|
|
|
|
},
|
2016-02-12 23:53:35 -06:00
|
|
|
Token::Str("a1"),
|
|
|
|
Token::I32(1),
|
|
|
|
Token::Str("a2"),
|
|
|
|
Token::I32(2),
|
|
|
|
Token::Str("a3"),
|
|
|
|
Token::I32(3),
|
2016-04-13 01:42:24 -05:00
|
|
|
Token::Str("a4"),
|
|
|
|
Token::I32(4),
|
|
|
|
Token::Str("a5"),
|
|
|
|
Token::I32(5),
|
2016-02-13 00:05:02 -06:00
|
|
|
Token::StructEnd,
|
2017-04-13 14:28:23 -05:00
|
|
|
],
|
2016-02-12 23:53:35 -06:00
|
|
|
);
|
|
|
|
|
|
|
|
assert_de_tokens(
|
2017-04-13 14:28:23 -05:00
|
|
|
&DefaultStruct {
|
2017-12-23 22:13:08 -06:00
|
|
|
a1: 1,
|
|
|
|
a2: 0,
|
|
|
|
a3: 123,
|
|
|
|
a4: 0,
|
|
|
|
a5: 123,
|
|
|
|
},
|
2016-06-29 01:50:19 -05:00
|
|
|
&[
|
2017-12-23 22:13:08 -06:00
|
|
|
Token::Struct {
|
|
|
|
name: "DefaultStruct",
|
|
|
|
len: 3,
|
|
|
|
},
|
2016-02-12 23:53:35 -06:00
|
|
|
Token::Str("a1"),
|
|
|
|
Token::I32(1),
|
2016-02-13 00:05:02 -06:00
|
|
|
Token::StructEnd,
|
2017-04-13 14:28:23 -05:00
|
|
|
],
|
2016-02-12 23:53:35 -06:00
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2018-12-10 23:47:56 -06:00
|
|
|
#[test]
|
|
|
|
fn test_default_tuple() {
|
|
|
|
assert_de_tokens(
|
|
|
|
&DefaultTupleStruct(1, 2, 3),
|
|
|
|
&[
|
|
|
|
Token::TupleStruct {
|
|
|
|
name: "DefaultTupleStruct",
|
|
|
|
len: 3,
|
|
|
|
},
|
|
|
|
Token::I32(1),
|
|
|
|
Token::I32(2),
|
|
|
|
Token::I32(3),
|
|
|
|
Token::TupleStructEnd,
|
|
|
|
],
|
|
|
|
);
|
|
|
|
|
|
|
|
assert_de_tokens(
|
|
|
|
&DefaultTupleStruct(1, 0, 123),
|
|
|
|
&[
|
|
|
|
Token::TupleStruct {
|
|
|
|
name: "DefaultTupleStruct",
|
|
|
|
len: 3,
|
|
|
|
},
|
|
|
|
Token::I32(1),
|
|
|
|
Token::TupleStructEnd,
|
|
|
|
],
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2016-02-12 23:53:35 -06:00
|
|
|
#[derive(Debug, PartialEq, Serialize, Deserialize)]
|
2018-12-10 23:47:56 -06:00
|
|
|
enum DefaultStructVariant<A, B, C, D, E>
|
2017-04-13 14:28:23 -05:00
|
|
|
where
|
|
|
|
C: MyDefault,
|
|
|
|
E: MyDefault,
|
2016-04-13 01:42:24 -05:00
|
|
|
{
|
2016-02-12 23:53:35 -06:00
|
|
|
Struct {
|
|
|
|
a1: A,
|
2017-12-23 22:24:57 -06:00
|
|
|
#[serde(default)]
|
|
|
|
a2: B,
|
|
|
|
#[serde(default = "MyDefault::my_default")]
|
|
|
|
a3: C,
|
|
|
|
#[serde(skip_deserializing)]
|
|
|
|
a4: D,
|
|
|
|
#[serde(skip_deserializing, default = "MyDefault::my_default")]
|
|
|
|
a5: E,
|
2017-04-13 14:28:23 -05:00
|
|
|
},
|
2015-04-02 00:14:28 -05:00
|
|
|
}
|
|
|
|
|
2018-12-10 23:47:56 -06:00
|
|
|
#[derive(Debug, PartialEq, Serialize, Deserialize)]
|
|
|
|
enum DefaultTupleVariant<A, B, C>
|
|
|
|
where
|
|
|
|
C: MyDefault,
|
|
|
|
{
|
|
|
|
Tuple(
|
|
|
|
A,
|
2018-12-11 00:09:02 -06:00
|
|
|
#[serde(default)] B,
|
|
|
|
#[serde(default = "MyDefault::my_default")] C,
|
2018-12-10 23:47:56 -06:00
|
|
|
),
|
|
|
|
}
|
|
|
|
|
2015-04-02 00:14:28 -05:00
|
|
|
#[test]
|
2018-12-10 23:47:56 -06:00
|
|
|
fn test_default_struct_variant() {
|
2015-08-27 22:01:09 -05:00
|
|
|
assert_de_tokens(
|
2018-12-10 23:47:56 -06:00
|
|
|
&DefaultStructVariant::Struct {
|
2017-12-23 22:13:08 -06:00
|
|
|
a1: 1,
|
|
|
|
a2: 2,
|
|
|
|
a3: 3,
|
|
|
|
a4: 0,
|
|
|
|
a5: 123,
|
|
|
|
},
|
2016-06-29 01:50:19 -05:00
|
|
|
&[
|
2017-12-23 22:13:08 -06:00
|
|
|
Token::StructVariant {
|
2018-12-10 23:47:56 -06:00
|
|
|
name: "DefaultStructVariant",
|
2017-12-23 22:13:08 -06:00
|
|
|
variant: "Struct",
|
|
|
|
len: 3,
|
|
|
|
},
|
2015-08-27 22:01:09 -05:00
|
|
|
Token::Str("a1"),
|
|
|
|
Token::I32(1),
|
|
|
|
Token::Str("a2"),
|
|
|
|
Token::I32(2),
|
2016-02-12 23:53:35 -06:00
|
|
|
Token::Str("a3"),
|
|
|
|
Token::I32(3),
|
2016-04-13 01:42:24 -05:00
|
|
|
Token::Str("a4"),
|
|
|
|
Token::I32(4),
|
|
|
|
Token::Str("a5"),
|
|
|
|
Token::I32(5),
|
2017-04-05 12:40:14 -05:00
|
|
|
Token::StructVariantEnd,
|
2017-04-13 14:28:23 -05:00
|
|
|
],
|
2015-08-27 22:01:09 -05:00
|
|
|
);
|
|
|
|
|
|
|
|
assert_de_tokens(
|
2018-12-10 23:47:56 -06:00
|
|
|
&DefaultStructVariant::Struct {
|
2017-12-23 22:13:08 -06:00
|
|
|
a1: 1,
|
|
|
|
a2: 0,
|
|
|
|
a3: 123,
|
|
|
|
a4: 0,
|
|
|
|
a5: 123,
|
|
|
|
},
|
2016-06-29 01:50:19 -05:00
|
|
|
&[
|
2017-12-23 22:13:08 -06:00
|
|
|
Token::StructVariant {
|
2018-12-10 23:47:56 -06:00
|
|
|
name: "DefaultStructVariant",
|
2017-12-23 22:13:08 -06:00
|
|
|
variant: "Struct",
|
|
|
|
len: 3,
|
|
|
|
},
|
2015-08-27 22:01:09 -05:00
|
|
|
Token::Str("a1"),
|
|
|
|
Token::I32(1),
|
2017-04-05 12:40:14 -05:00
|
|
|
Token::StructVariantEnd,
|
2017-04-13 14:28:23 -05:00
|
|
|
],
|
2015-08-27 22:01:09 -05:00
|
|
|
);
|
2015-04-02 00:14:28 -05:00
|
|
|
}
|
|
|
|
|
2018-12-10 23:47:56 -06:00
|
|
|
#[test]
|
|
|
|
fn test_default_tuple_variant() {
|
|
|
|
assert_de_tokens(
|
|
|
|
&DefaultTupleVariant::Tuple(1, 2, 3),
|
|
|
|
&[
|
|
|
|
Token::TupleVariant {
|
|
|
|
name: "DefaultTupleVariant",
|
|
|
|
variant: "Tuple",
|
|
|
|
len: 3,
|
|
|
|
},
|
|
|
|
Token::I32(1),
|
|
|
|
Token::I32(2),
|
|
|
|
Token::I32(3),
|
|
|
|
Token::TupleVariantEnd,
|
|
|
|
],
|
|
|
|
);
|
|
|
|
|
|
|
|
assert_de_tokens(
|
|
|
|
&DefaultTupleVariant::Tuple(1, 0, 123),
|
|
|
|
&[
|
|
|
|
Token::TupleVariant {
|
|
|
|
name: "DefaultTupleVariant",
|
|
|
|
variant: "Tuple",
|
|
|
|
len: 3,
|
|
|
|
},
|
|
|
|
Token::I32(1),
|
|
|
|
Token::TupleVariantEnd,
|
|
|
|
],
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2016-04-13 02:34:29 -05:00
|
|
|
// Does not implement std::default::Default.
|
|
|
|
#[derive(Debug, PartialEq, Deserialize)]
|
|
|
|
struct NoStdDefault(i8);
|
|
|
|
|
|
|
|
impl MyDefault for NoStdDefault {
|
|
|
|
fn my_default() -> Self {
|
|
|
|
NoStdDefault(123)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Debug, PartialEq, Deserialize)]
|
|
|
|
struct ContainsNoStdDefault<A: MyDefault> {
|
2017-12-23 22:24:57 -06:00
|
|
|
#[serde(default = "MyDefault::my_default")]
|
|
|
|
a: A,
|
2016-04-13 02:34:29 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
// Tests that a struct field does not need to implement std::default::Default if
|
|
|
|
// it is annotated with `default=...`.
|
|
|
|
#[test]
|
|
|
|
fn test_no_std_default() {
|
|
|
|
assert_de_tokens(
|
2017-12-23 22:13:08 -06:00
|
|
|
&ContainsNoStdDefault {
|
|
|
|
a: NoStdDefault(123),
|
|
|
|
},
|
|
|
|
&[
|
|
|
|
Token::Struct {
|
|
|
|
name: "ContainsNoStdDefault",
|
|
|
|
len: 1,
|
|
|
|
},
|
|
|
|
Token::StructEnd,
|
|
|
|
],
|
2016-04-13 02:34:29 -05:00
|
|
|
);
|
|
|
|
|
|
|
|
assert_de_tokens(
|
|
|
|
&ContainsNoStdDefault { a: NoStdDefault(8) },
|
2016-06-29 01:50:19 -05:00
|
|
|
&[
|
2017-12-23 22:13:08 -06:00
|
|
|
Token::Struct {
|
|
|
|
name: "ContainsNoStdDefault",
|
|
|
|
len: 1,
|
|
|
|
},
|
2016-04-13 02:34:29 -05:00
|
|
|
Token::Str("a"),
|
2017-12-23 22:13:08 -06:00
|
|
|
Token::NewtypeStruct {
|
|
|
|
name: "NoStdDefault",
|
|
|
|
},
|
2016-04-13 02:34:29 -05:00
|
|
|
Token::I8(8),
|
|
|
|
Token::StructEnd,
|
2017-04-13 14:28:23 -05:00
|
|
|
],
|
2016-04-13 02:34:29 -05:00
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Does not implement Deserialize.
|
|
|
|
#[derive(Debug, PartialEq)]
|
|
|
|
struct NotDeserializeStruct(i8);
|
|
|
|
|
|
|
|
impl Default for NotDeserializeStruct {
|
|
|
|
fn default() -> Self {
|
|
|
|
NotDeserializeStruct(123)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-05-07 21:57:44 -05:00
|
|
|
impl DeserializeWith for NotDeserializeStruct {
|
2017-03-27 00:56:58 -05:00
|
|
|
fn deserialize_with<'de, D>(_: D) -> Result<Self, D::Error>
|
2017-04-13 14:28:23 -05:00
|
|
|
where
|
|
|
|
D: Deserializer<'de>,
|
2016-05-07 21:57:44 -05:00
|
|
|
{
|
|
|
|
panic!()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-04-13 02:34:29 -05:00
|
|
|
// Does not implement Deserialize.
|
|
|
|
#[derive(Debug, PartialEq)]
|
2017-04-13 14:28:23 -05:00
|
|
|
enum NotDeserializeEnum {
|
|
|
|
Trouble,
|
|
|
|
}
|
2016-04-13 02:34:29 -05:00
|
|
|
|
|
|
|
impl MyDefault for NotDeserializeEnum {
|
|
|
|
fn my_default() -> Self {
|
|
|
|
NotDeserializeEnum::Trouble
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Debug, PartialEq, Deserialize)]
|
2016-05-07 21:57:44 -05:00
|
|
|
struct ContainsNotDeserialize<A, B, C: DeserializeWith, E: MyDefault> {
|
2017-12-23 22:24:57 -06:00
|
|
|
#[serde(skip_deserializing)]
|
|
|
|
a: A,
|
|
|
|
#[serde(skip_deserializing, default)]
|
|
|
|
b: B,
|
2018-11-21 03:13:17 -06:00
|
|
|
#[serde(deserialize_with = "DeserializeWith::deserialize_with", default)]
|
2017-12-23 22:24:57 -06:00
|
|
|
c: C,
|
|
|
|
#[serde(skip_deserializing, default = "MyDefault::my_default")]
|
|
|
|
e: E,
|
2016-04-13 02:34:29 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
// Tests that a struct field does not need to implement Deserialize if it is
|
|
|
|
// annotated with skip_deserializing, whether using the std Default or a
|
|
|
|
// custom default.
|
|
|
|
#[test]
|
|
|
|
fn test_elt_not_deserialize() {
|
|
|
|
assert_de_tokens(
|
|
|
|
&ContainsNotDeserialize {
|
2017-12-23 22:13:08 -06:00
|
|
|
a: NotDeserializeStruct(123),
|
|
|
|
b: NotDeserializeStruct(123),
|
|
|
|
c: NotDeserializeStruct(123),
|
|
|
|
e: NotDeserializeEnum::Trouble,
|
|
|
|
},
|
|
|
|
&[
|
|
|
|
Token::Struct {
|
|
|
|
name: "ContainsNotDeserialize",
|
|
|
|
len: 1,
|
|
|
|
},
|
|
|
|
Token::StructEnd,
|
|
|
|
],
|
2016-04-13 02:34:29 -05:00
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2016-02-15 18:02:09 -06:00
|
|
|
#[derive(Debug, PartialEq, Serialize, Deserialize)]
|
|
|
|
#[serde(deny_unknown_fields)]
|
|
|
|
struct DenyUnknown {
|
|
|
|
a1: i32,
|
|
|
|
}
|
|
|
|
|
2016-01-10 21:34:48 -06:00
|
|
|
#[test]
|
|
|
|
fn test_ignore_unknown() {
|
|
|
|
// 'Default' allows unknown. Basic smoke test of ignore...
|
|
|
|
assert_de_tokens(
|
2017-04-13 14:28:23 -05:00
|
|
|
&DefaultStruct {
|
2017-12-23 22:13:08 -06:00
|
|
|
a1: 1,
|
|
|
|
a2: 2,
|
|
|
|
a3: 3,
|
|
|
|
a4: 0,
|
|
|
|
a5: 123,
|
|
|
|
},
|
2016-06-29 01:50:19 -05:00
|
|
|
&[
|
2017-12-23 22:13:08 -06:00
|
|
|
Token::Struct {
|
|
|
|
name: "DefaultStruct",
|
|
|
|
len: 3,
|
|
|
|
},
|
2016-01-10 21:34:48 -06:00
|
|
|
Token::Str("whoops1"),
|
|
|
|
Token::I32(2),
|
|
|
|
Token::Str("a1"),
|
|
|
|
Token::I32(1),
|
|
|
|
Token::Str("whoops2"),
|
2017-04-19 15:06:31 -05:00
|
|
|
Token::Seq { len: Some(1) },
|
2016-01-10 21:34:48 -06:00
|
|
|
Token::I32(2),
|
|
|
|
Token::SeqEnd,
|
|
|
|
Token::Str("a2"),
|
|
|
|
Token::I32(2),
|
|
|
|
Token::Str("whoops3"),
|
|
|
|
Token::I32(2),
|
2016-02-12 23:53:35 -06:00
|
|
|
Token::Str("a3"),
|
|
|
|
Token::I32(3),
|
2016-02-13 00:05:02 -06:00
|
|
|
Token::StructEnd,
|
2017-04-13 14:28:23 -05:00
|
|
|
],
|
2016-01-10 21:34:48 -06:00
|
|
|
);
|
|
|
|
|
2016-02-15 18:02:09 -06:00
|
|
|
assert_de_tokens_error::<DenyUnknown>(
|
2016-06-29 01:50:19 -05:00
|
|
|
&[
|
2017-12-23 22:13:08 -06:00
|
|
|
Token::Struct {
|
|
|
|
name: "DenyUnknown",
|
|
|
|
len: 1,
|
|
|
|
},
|
2016-01-10 21:34:48 -06:00
|
|
|
Token::Str("a1"),
|
|
|
|
Token::I32(1),
|
|
|
|
Token::Str("whoops"),
|
|
|
|
],
|
2017-04-19 13:38:57 -05:00
|
|
|
"unknown field `whoops`, expected `a1`",
|
2016-01-10 21:34:48 -06:00
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2016-02-15 18:02:09 -06:00
|
|
|
#[derive(Debug, PartialEq, Serialize, Deserialize)]
|
2017-12-23 22:13:08 -06:00
|
|
|
#[serde(rename = "Superhero")]
|
2016-02-15 18:02:09 -06:00
|
|
|
struct RenameStruct {
|
|
|
|
a1: i32,
|
2017-12-23 22:24:57 -06:00
|
|
|
#[serde(rename = "a3")]
|
|
|
|
a2: i32,
|
2016-02-15 18:02:09 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Debug, PartialEq, Serialize, Deserialize)]
|
2017-12-23 22:13:08 -06:00
|
|
|
#[serde(rename(serialize = "SuperheroSer", deserialize = "SuperheroDe"))]
|
2016-02-15 18:02:09 -06:00
|
|
|
struct RenameStructSerializeDeserialize {
|
|
|
|
a1: i32,
|
2017-12-23 22:24:57 -06:00
|
|
|
#[serde(rename(serialize = "a4", deserialize = "a5"))]
|
|
|
|
a2: i32,
|
2016-02-15 18:02:09 -06:00
|
|
|
}
|
|
|
|
|
2019-01-15 10:35:09 -06:00
|
|
|
#[derive(Debug, PartialEq, Deserialize)]
|
|
|
|
#[serde(deny_unknown_fields)]
|
|
|
|
struct AliasStruct {
|
|
|
|
a1: i32,
|
|
|
|
#[serde(alias = "a3")]
|
|
|
|
a2: i32,
|
|
|
|
#[serde(alias = "a5", rename = "a6")]
|
|
|
|
a4: i32,
|
|
|
|
}
|
|
|
|
|
2015-04-02 00:14:28 -05:00
|
|
|
#[test]
|
2016-02-08 10:00:38 -06:00
|
|
|
fn test_rename_struct() {
|
2015-08-27 22:01:09 -05:00
|
|
|
assert_tokens(
|
2016-02-08 10:00:38 -06:00
|
|
|
&RenameStruct { a1: 1, a2: 2 },
|
2016-06-29 01:50:19 -05:00
|
|
|
&[
|
2017-12-23 22:13:08 -06:00
|
|
|
Token::Struct {
|
|
|
|
name: "Superhero",
|
|
|
|
len: 2,
|
|
|
|
},
|
2015-08-27 22:01:09 -05:00
|
|
|
Token::Str("a1"),
|
|
|
|
Token::I32(1),
|
|
|
|
Token::Str("a3"),
|
|
|
|
Token::I32(2),
|
2016-02-13 00:05:02 -06:00
|
|
|
Token::StructEnd,
|
2017-04-13 14:28:23 -05:00
|
|
|
],
|
2015-08-27 22:01:09 -05:00
|
|
|
);
|
2015-04-21 09:57:36 -05:00
|
|
|
|
2016-02-08 12:35:42 -06:00
|
|
|
assert_ser_tokens(
|
2016-02-08 10:00:38 -06:00
|
|
|
&RenameStructSerializeDeserialize { a1: 1, a2: 2 },
|
2016-02-08 12:35:42 -06:00
|
|
|
&[
|
2017-12-23 22:13:08 -06:00
|
|
|
Token::Struct {
|
|
|
|
name: "SuperheroSer",
|
|
|
|
len: 2,
|
|
|
|
},
|
2016-02-08 12:35:42 -06:00
|
|
|
Token::Str("a1"),
|
|
|
|
Token::I32(1),
|
|
|
|
Token::Str("a4"),
|
|
|
|
Token::I32(2),
|
2016-02-13 00:05:02 -06:00
|
|
|
Token::StructEnd,
|
2017-04-13 14:28:23 -05:00
|
|
|
],
|
2016-02-08 12:35:42 -06:00
|
|
|
);
|
|
|
|
|
|
|
|
assert_de_tokens(
|
2016-02-08 10:00:38 -06:00
|
|
|
&RenameStructSerializeDeserialize { a1: 1, a2: 2 },
|
2016-06-29 01:50:19 -05:00
|
|
|
&[
|
2017-12-23 22:13:08 -06:00
|
|
|
Token::Struct {
|
|
|
|
name: "SuperheroDe",
|
|
|
|
len: 2,
|
|
|
|
},
|
2016-02-08 12:35:42 -06:00
|
|
|
Token::Str("a1"),
|
|
|
|
Token::I32(1),
|
|
|
|
Token::Str("a5"),
|
|
|
|
Token::I32(2),
|
2016-02-13 00:05:02 -06:00
|
|
|
Token::StructEnd,
|
2017-04-13 14:28:23 -05:00
|
|
|
],
|
2016-02-08 12:35:42 -06:00
|
|
|
);
|
2019-01-15 10:35:09 -06:00
|
|
|
|
|
|
|
assert_de_tokens(
|
2019-02-01 23:02:57 -06:00
|
|
|
&AliasStruct {
|
|
|
|
a1: 1,
|
|
|
|
a2: 2,
|
|
|
|
a4: 3,
|
|
|
|
},
|
2019-01-15 10:35:09 -06:00
|
|
|
&[
|
|
|
|
Token::Struct {
|
|
|
|
name: "AliasStruct",
|
|
|
|
len: 3,
|
|
|
|
},
|
|
|
|
Token::Str("a1"),
|
|
|
|
Token::I32(1),
|
|
|
|
Token::Str("a2"),
|
|
|
|
Token::I32(2),
|
|
|
|
Token::Str("a5"),
|
|
|
|
Token::I32(3),
|
|
|
|
Token::StructEnd,
|
|
|
|
],
|
|
|
|
);
|
|
|
|
|
|
|
|
assert_de_tokens(
|
2019-02-01 23:02:57 -06:00
|
|
|
&AliasStruct {
|
|
|
|
a1: 1,
|
|
|
|
a2: 2,
|
|
|
|
a4: 3,
|
|
|
|
},
|
2019-01-15 10:35:09 -06:00
|
|
|
&[
|
|
|
|
Token::Struct {
|
|
|
|
name: "AliasStruct",
|
|
|
|
len: 3,
|
|
|
|
},
|
|
|
|
Token::Str("a1"),
|
|
|
|
Token::I32(1),
|
|
|
|
Token::Str("a3"),
|
|
|
|
Token::I32(2),
|
|
|
|
Token::Str("a6"),
|
|
|
|
Token::I32(3),
|
|
|
|
Token::StructEnd,
|
|
|
|
],
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_unknown_field_rename_struct() {
|
|
|
|
assert_de_tokens_error::<AliasStruct>(
|
|
|
|
&[
|
|
|
|
Token::Struct {
|
|
|
|
name: "AliasStruct",
|
|
|
|
len: 3,
|
|
|
|
},
|
|
|
|
Token::Str("a1"),
|
|
|
|
Token::I32(1),
|
|
|
|
Token::Str("a3"),
|
|
|
|
Token::I32(2),
|
|
|
|
Token::Str("a4"),
|
|
|
|
Token::I32(3),
|
|
|
|
],
|
2023-03-05 01:14:51 -06:00
|
|
|
"unknown field `a4`, expected one of `a1`, `a3`, `a2`, `a5`, `a6`",
|
2019-01-15 10:35:09 -06:00
|
|
|
);
|
2016-02-08 12:35:42 -06:00
|
|
|
}
|
|
|
|
|
2016-02-15 18:02:09 -06:00
|
|
|
#[derive(Debug, PartialEq, Serialize, Deserialize)]
|
2017-12-23 22:13:08 -06:00
|
|
|
#[serde(rename = "Superhero")]
|
2016-02-15 18:02:09 -06:00
|
|
|
enum RenameEnum {
|
2017-12-23 22:24:57 -06:00
|
|
|
#[serde(rename = "bruce_wayne")]
|
|
|
|
Batman,
|
|
|
|
#[serde(rename = "clark_kent")]
|
|
|
|
Superman(i8),
|
|
|
|
#[serde(rename = "diana_prince")]
|
|
|
|
WonderWoman(i8, i8),
|
|
|
|
#[serde(rename = "barry_allan")]
|
|
|
|
Flash {
|
|
|
|
#[serde(rename = "b")]
|
|
|
|
a: i32,
|
|
|
|
},
|
2016-02-15 18:02:09 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Debug, PartialEq, Deserialize, Serialize)]
|
2017-12-23 22:13:08 -06:00
|
|
|
#[serde(rename(serialize = "SuperheroSer", deserialize = "SuperheroDe"))]
|
2016-02-15 18:02:09 -06:00
|
|
|
enum RenameEnumSerializeDeserialize<A> {
|
2017-12-23 22:13:08 -06:00
|
|
|
#[serde(rename(serialize = "dick_grayson", deserialize = "jason_todd"))]
|
2016-02-15 18:02:09 -06:00
|
|
|
Robin {
|
|
|
|
a: i8,
|
2017-12-23 22:13:08 -06:00
|
|
|
#[serde(rename(serialize = "c"))]
|
|
|
|
#[serde(rename(deserialize = "d"))]
|
2016-02-15 18:02:09 -06:00
|
|
|
b: A,
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
2019-01-15 10:35:09 -06:00
|
|
|
#[derive(Debug, PartialEq, Deserialize)]
|
|
|
|
#[serde(deny_unknown_fields)]
|
|
|
|
enum AliasEnum {
|
|
|
|
#[serde(rename = "sailor_moon", alias = "usagi_tsukino")]
|
|
|
|
SailorMoon {
|
|
|
|
a: i8,
|
|
|
|
#[serde(alias = "c")]
|
|
|
|
b: i8,
|
|
|
|
#[serde(alias = "e", rename = "f")]
|
|
|
|
d: i8,
|
2019-02-01 23:02:57 -06:00
|
|
|
},
|
2019-01-15 10:35:09 -06:00
|
|
|
}
|
|
|
|
|
2016-02-08 12:35:42 -06:00
|
|
|
#[test]
|
2016-02-08 10:00:38 -06:00
|
|
|
fn test_rename_enum() {
|
|
|
|
assert_tokens(
|
|
|
|
&RenameEnum::Batman,
|
2018-04-30 03:41:22 -05:00
|
|
|
&[Token::UnitVariant {
|
|
|
|
name: "Superhero",
|
|
|
|
variant: "bruce_wayne",
|
|
|
|
}],
|
2016-02-08 12:35:42 -06:00
|
|
|
);
|
|
|
|
|
2016-02-08 10:00:38 -06:00
|
|
|
assert_tokens(
|
|
|
|
&RenameEnum::Superman(0),
|
2016-06-29 01:50:19 -05:00
|
|
|
&[
|
2017-12-23 22:13:08 -06:00
|
|
|
Token::NewtypeVariant {
|
|
|
|
name: "Superhero",
|
|
|
|
variant: "clark_kent",
|
|
|
|
},
|
2016-02-08 10:00:38 -06:00
|
|
|
Token::I8(0),
|
2017-04-13 14:28:23 -05:00
|
|
|
],
|
2016-02-08 10:00:38 -06:00
|
|
|
);
|
|
|
|
|
|
|
|
assert_tokens(
|
|
|
|
&RenameEnum::WonderWoman(0, 1),
|
2016-06-29 01:50:19 -05:00
|
|
|
&[
|
2017-12-23 22:13:08 -06:00
|
|
|
Token::TupleVariant {
|
|
|
|
name: "Superhero",
|
|
|
|
variant: "diana_prince",
|
|
|
|
len: 2,
|
|
|
|
},
|
2016-02-08 10:00:38 -06:00
|
|
|
Token::I8(0),
|
|
|
|
Token::I8(1),
|
2017-04-05 12:40:14 -05:00
|
|
|
Token::TupleVariantEnd,
|
2017-04-13 14:28:23 -05:00
|
|
|
],
|
2016-02-08 10:00:38 -06:00
|
|
|
);
|
|
|
|
|
|
|
|
assert_tokens(
|
|
|
|
&RenameEnum::Flash { a: 1 },
|
2016-06-29 01:50:19 -05:00
|
|
|
&[
|
2017-12-23 22:13:08 -06:00
|
|
|
Token::StructVariant {
|
|
|
|
name: "Superhero",
|
|
|
|
variant: "barry_allan",
|
|
|
|
len: 1,
|
|
|
|
},
|
2016-02-08 10:00:38 -06:00
|
|
|
Token::Str("b"),
|
|
|
|
Token::I32(1),
|
2017-04-05 12:40:14 -05:00
|
|
|
Token::StructVariantEnd,
|
2017-04-13 14:28:23 -05:00
|
|
|
],
|
2016-02-08 12:35:42 -06:00
|
|
|
);
|
|
|
|
|
|
|
|
assert_ser_tokens(
|
2016-02-08 10:00:38 -06:00
|
|
|
&RenameEnumSerializeDeserialize::Robin {
|
2017-12-23 22:13:08 -06:00
|
|
|
a: 0,
|
|
|
|
b: String::new(),
|
|
|
|
},
|
2016-02-08 12:35:42 -06:00
|
|
|
&[
|
2017-12-23 22:13:08 -06:00
|
|
|
Token::StructVariant {
|
|
|
|
name: "SuperheroSer",
|
|
|
|
variant: "dick_grayson",
|
|
|
|
len: 2,
|
|
|
|
},
|
2016-02-08 12:35:42 -06:00
|
|
|
Token::Str("a"),
|
|
|
|
Token::I8(0),
|
|
|
|
Token::Str("c"),
|
|
|
|
Token::Str(""),
|
2017-04-05 12:40:14 -05:00
|
|
|
Token::StructVariantEnd,
|
2017-04-13 14:28:23 -05:00
|
|
|
],
|
2016-02-08 12:35:42 -06:00
|
|
|
);
|
|
|
|
|
|
|
|
assert_de_tokens(
|
2016-02-08 10:00:38 -06:00
|
|
|
&RenameEnumSerializeDeserialize::Robin {
|
2017-12-23 22:13:08 -06:00
|
|
|
a: 0,
|
|
|
|
b: String::new(),
|
|
|
|
},
|
2016-06-29 01:50:19 -05:00
|
|
|
&[
|
2017-12-23 22:13:08 -06:00
|
|
|
Token::StructVariant {
|
|
|
|
name: "SuperheroDe",
|
|
|
|
variant: "jason_todd",
|
|
|
|
len: 2,
|
|
|
|
},
|
2016-02-08 12:35:42 -06:00
|
|
|
Token::Str("a"),
|
|
|
|
Token::I8(0),
|
|
|
|
Token::Str("d"),
|
|
|
|
Token::Str(""),
|
2017-04-05 12:40:14 -05:00
|
|
|
Token::StructVariantEnd,
|
2017-04-13 14:28:23 -05:00
|
|
|
],
|
2016-02-08 10:03:46 -06:00
|
|
|
);
|
2019-01-15 10:35:09 -06:00
|
|
|
|
|
|
|
assert_de_tokens(
|
2019-02-01 23:02:57 -06:00
|
|
|
&AliasEnum::SailorMoon { a: 0, b: 1, d: 2 },
|
2019-01-15 10:35:09 -06:00
|
|
|
&[
|
|
|
|
Token::StructVariant {
|
|
|
|
name: "AliasEnum",
|
|
|
|
variant: "sailor_moon",
|
2023-03-05 01:14:51 -06:00
|
|
|
len: 5,
|
2019-01-15 10:35:09 -06:00
|
|
|
},
|
|
|
|
Token::Str("a"),
|
|
|
|
Token::I8(0),
|
|
|
|
Token::Str("b"),
|
|
|
|
Token::I8(1),
|
|
|
|
Token::Str("e"),
|
|
|
|
Token::I8(2),
|
|
|
|
Token::StructVariantEnd,
|
|
|
|
],
|
|
|
|
);
|
|
|
|
|
|
|
|
assert_de_tokens(
|
2019-02-01 23:02:57 -06:00
|
|
|
&AliasEnum::SailorMoon { a: 0, b: 1, d: 2 },
|
2019-01-15 10:35:09 -06:00
|
|
|
&[
|
|
|
|
Token::StructVariant {
|
|
|
|
name: "AliasEnum",
|
|
|
|
variant: "usagi_tsukino",
|
2023-03-05 01:14:51 -06:00
|
|
|
len: 5,
|
2019-01-15 10:35:09 -06:00
|
|
|
},
|
|
|
|
Token::Str("a"),
|
|
|
|
Token::I8(0),
|
|
|
|
Token::Str("c"),
|
|
|
|
Token::I8(1),
|
|
|
|
Token::Str("f"),
|
|
|
|
Token::I8(2),
|
|
|
|
Token::StructVariantEnd,
|
|
|
|
],
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_unknown_field_rename_enum() {
|
|
|
|
assert_de_tokens_error::<AliasEnum>(
|
2019-02-01 23:02:57 -06:00
|
|
|
&[Token::StructVariant {
|
|
|
|
name: "AliasEnum",
|
|
|
|
variant: "SailorMoon",
|
|
|
|
len: 3,
|
|
|
|
}],
|
2019-01-15 10:35:09 -06:00
|
|
|
"unknown variant `SailorMoon`, expected `sailor_moon`",
|
|
|
|
);
|
|
|
|
|
|
|
|
assert_de_tokens_error::<AliasEnum>(
|
|
|
|
&[
|
|
|
|
Token::StructVariant {
|
|
|
|
name: "AliasEnum",
|
|
|
|
variant: "usagi_tsukino",
|
2023-03-05 01:14:51 -06:00
|
|
|
len: 5,
|
2019-01-15 10:35:09 -06:00
|
|
|
},
|
|
|
|
Token::Str("a"),
|
|
|
|
Token::I8(0),
|
|
|
|
Token::Str("c"),
|
|
|
|
Token::I8(1),
|
|
|
|
Token::Str("d"),
|
|
|
|
Token::I8(2),
|
|
|
|
],
|
2023-03-05 01:14:51 -06:00
|
|
|
"unknown field `d`, expected one of `a`, `c`, `b`, `e`, `f`",
|
2019-01-15 10:35:09 -06:00
|
|
|
);
|
2016-02-08 10:03:46 -06:00
|
|
|
}
|
|
|
|
|
2016-02-15 18:02:09 -06:00
|
|
|
#[derive(Debug, PartialEq, Serialize)]
|
2017-04-13 14:28:23 -05:00
|
|
|
struct SkipSerializingStruct<'a, B, C>
|
|
|
|
where
|
|
|
|
C: ShouldSkip,
|
|
|
|
{
|
2016-02-15 18:02:09 -06:00
|
|
|
a: &'a i8,
|
2017-12-23 22:24:57 -06:00
|
|
|
#[serde(skip_serializing)]
|
|
|
|
b: B,
|
|
|
|
#[serde(skip_serializing_if = "ShouldSkip::should_skip")]
|
|
|
|
c: C,
|
2015-07-23 10:07:49 -05:00
|
|
|
}
|
2015-09-07 18:44:56 -05:00
|
|
|
|
|
|
|
#[test]
|
2016-02-15 18:02:09 -06:00
|
|
|
fn test_skip_serializing_struct() {
|
|
|
|
let a = 1;
|
2015-09-07 18:44:56 -05:00
|
|
|
assert_ser_tokens(
|
2017-04-13 14:28:23 -05:00
|
|
|
&SkipSerializingStruct { a: &a, b: 2, c: 3 },
|
2015-09-07 18:44:56 -05:00
|
|
|
&[
|
2017-12-23 22:13:08 -06:00
|
|
|
Token::Struct {
|
|
|
|
name: "SkipSerializingStruct",
|
|
|
|
len: 2,
|
|
|
|
},
|
2015-09-07 18:44:56 -05:00
|
|
|
Token::Str("a"),
|
|
|
|
Token::I8(1),
|
2016-02-13 00:05:02 -06:00
|
|
|
Token::Str("c"),
|
|
|
|
Token::I32(3),
|
|
|
|
Token::StructEnd,
|
2017-04-13 14:28:23 -05:00
|
|
|
],
|
2015-09-07 18:44:56 -05:00
|
|
|
);
|
|
|
|
|
2016-02-15 18:02:09 -06:00
|
|
|
assert_ser_tokens(
|
|
|
|
&SkipSerializingStruct {
|
2017-12-23 22:13:08 -06:00
|
|
|
a: &a,
|
|
|
|
b: 2,
|
|
|
|
c: 123,
|
|
|
|
},
|
2016-02-15 18:02:09 -06:00
|
|
|
&[
|
2017-12-23 22:13:08 -06:00
|
|
|
Token::Struct {
|
|
|
|
name: "SkipSerializingStruct",
|
|
|
|
len: 1,
|
|
|
|
},
|
2015-09-07 18:44:56 -05:00
|
|
|
Token::Str("a"),
|
|
|
|
Token::I8(1),
|
2016-02-13 00:05:02 -06:00
|
|
|
Token::StructEnd,
|
2017-04-13 14:28:23 -05:00
|
|
|
],
|
2015-09-07 18:44:56 -05:00
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2018-05-08 13:37:52 -05:00
|
|
|
#[derive(Debug, PartialEq, Serialize)]
|
|
|
|
struct SkipSerializingTupleStruct<'a, B, C>(
|
|
|
|
&'a i8,
|
|
|
|
#[serde(skip_serializing)] B,
|
|
|
|
#[serde(skip_serializing_if = "ShouldSkip::should_skip")] C,
|
|
|
|
)
|
|
|
|
where
|
|
|
|
C: ShouldSkip;
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_skip_serializing_tuple_struct() {
|
|
|
|
let a = 1;
|
|
|
|
assert_ser_tokens(
|
|
|
|
&SkipSerializingTupleStruct(&a, 2, 3),
|
|
|
|
&[
|
|
|
|
Token::TupleStruct {
|
|
|
|
name: "SkipSerializingTupleStruct",
|
|
|
|
len: 2,
|
|
|
|
},
|
|
|
|
Token::I8(1),
|
|
|
|
Token::I32(3),
|
|
|
|
Token::TupleStructEnd,
|
|
|
|
],
|
|
|
|
);
|
|
|
|
|
|
|
|
assert_ser_tokens(
|
|
|
|
&SkipSerializingTupleStruct(&a, 2, 123),
|
|
|
|
&[
|
|
|
|
Token::TupleStruct {
|
|
|
|
name: "SkipSerializingTupleStruct",
|
2018-05-08 13:49:37 -05:00
|
|
|
len: 1,
|
2018-05-08 13:37:52 -05:00
|
|
|
},
|
|
|
|
Token::I8(1),
|
|
|
|
Token::TupleStructEnd,
|
|
|
|
],
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2017-05-16 04:33:26 -05:00
|
|
|
#[derive(Debug, PartialEq, Serialize, Deserialize)]
|
2017-12-23 22:13:08 -06:00
|
|
|
struct SkipStruct<B> {
|
2017-05-16 04:33:26 -05:00
|
|
|
a: i8,
|
2017-12-23 22:24:57 -06:00
|
|
|
#[serde(skip)]
|
|
|
|
b: B,
|
2017-05-16 04:33:26 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_skip_struct() {
|
|
|
|
assert_ser_tokens(
|
|
|
|
&SkipStruct { a: 1, b: 2 },
|
|
|
|
&[
|
2017-12-23 22:13:08 -06:00
|
|
|
Token::Struct {
|
|
|
|
name: "SkipStruct",
|
|
|
|
len: 1,
|
|
|
|
},
|
2017-05-16 04:33:26 -05:00
|
|
|
Token::Str("a"),
|
|
|
|
Token::I8(1),
|
|
|
|
Token::StructEnd,
|
|
|
|
],
|
|
|
|
);
|
|
|
|
|
|
|
|
assert_de_tokens(
|
|
|
|
&SkipStruct { a: 1, b: 0 },
|
|
|
|
&[
|
2017-12-23 22:13:08 -06:00
|
|
|
Token::Struct {
|
|
|
|
name: "SkipStruct",
|
|
|
|
len: 1,
|
|
|
|
},
|
2017-05-16 04:33:26 -05:00
|
|
|
Token::Str("a"),
|
|
|
|
Token::I8(1),
|
|
|
|
Token::StructEnd,
|
|
|
|
],
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2016-02-15 18:02:09 -06:00
|
|
|
#[derive(Debug, PartialEq, Serialize)]
|
2017-04-13 14:28:23 -05:00
|
|
|
enum SkipSerializingEnum<'a, B, C>
|
|
|
|
where
|
|
|
|
C: ShouldSkip,
|
|
|
|
{
|
2016-02-15 18:02:09 -06:00
|
|
|
Struct {
|
|
|
|
a: &'a i8,
|
2017-12-23 22:24:57 -06:00
|
|
|
#[serde(skip_serializing)]
|
|
|
|
_b: B,
|
|
|
|
#[serde(skip_serializing_if = "ShouldSkip::should_skip")]
|
|
|
|
c: C,
|
2017-04-13 14:28:23 -05:00
|
|
|
},
|
2018-05-08 13:37:52 -05:00
|
|
|
Tuple(
|
|
|
|
&'a i8,
|
|
|
|
#[serde(skip_serializing)] B,
|
|
|
|
#[serde(skip_serializing_if = "ShouldSkip::should_skip")] C,
|
|
|
|
),
|
2016-02-15 18:02:09 -06:00
|
|
|
}
|
|
|
|
|
2015-09-07 18:44:56 -05:00
|
|
|
#[test]
|
2016-02-15 18:02:09 -06:00
|
|
|
fn test_skip_serializing_enum() {
|
|
|
|
let a = 1;
|
2015-09-07 18:44:56 -05:00
|
|
|
assert_ser_tokens(
|
2017-04-13 14:28:23 -05:00
|
|
|
&SkipSerializingEnum::Struct { a: &a, _b: 2, c: 3 },
|
2015-09-07 18:44:56 -05:00
|
|
|
&[
|
2017-12-23 22:13:08 -06:00
|
|
|
Token::StructVariant {
|
|
|
|
name: "SkipSerializingEnum",
|
|
|
|
variant: "Struct",
|
|
|
|
len: 2,
|
|
|
|
},
|
2015-09-07 18:44:56 -05:00
|
|
|
Token::Str("a"),
|
|
|
|
Token::I8(1),
|
2016-02-13 00:05:02 -06:00
|
|
|
Token::Str("c"),
|
|
|
|
Token::I32(3),
|
2017-04-05 12:40:14 -05:00
|
|
|
Token::StructVariantEnd,
|
2017-04-13 14:28:23 -05:00
|
|
|
],
|
2015-09-07 18:44:56 -05:00
|
|
|
);
|
|
|
|
|
|
|
|
assert_ser_tokens(
|
2016-02-15 18:02:09 -06:00
|
|
|
&SkipSerializingEnum::Struct {
|
2017-12-23 22:13:08 -06:00
|
|
|
a: &a,
|
|
|
|
_b: 2,
|
|
|
|
c: 123,
|
|
|
|
},
|
2015-09-07 18:44:56 -05:00
|
|
|
&[
|
2017-12-23 22:13:08 -06:00
|
|
|
Token::StructVariant {
|
|
|
|
name: "SkipSerializingEnum",
|
|
|
|
variant: "Struct",
|
|
|
|
len: 1,
|
|
|
|
},
|
2015-09-07 18:44:56 -05:00
|
|
|
Token::Str("a"),
|
|
|
|
Token::I8(1),
|
2017-04-05 12:40:14 -05:00
|
|
|
Token::StructVariantEnd,
|
2017-04-13 14:28:23 -05:00
|
|
|
],
|
2015-09-07 18:44:56 -05:00
|
|
|
);
|
2018-05-08 13:37:52 -05:00
|
|
|
|
|
|
|
assert_ser_tokens(
|
|
|
|
&SkipSerializingEnum::Tuple(&a, 2, 3),
|
|
|
|
&[
|
|
|
|
Token::TupleVariant {
|
|
|
|
name: "SkipSerializingEnum",
|
|
|
|
variant: "Tuple",
|
|
|
|
len: 2,
|
|
|
|
},
|
|
|
|
Token::I8(1),
|
|
|
|
Token::I32(3),
|
|
|
|
Token::TupleVariantEnd,
|
|
|
|
],
|
|
|
|
);
|
|
|
|
|
|
|
|
assert_ser_tokens(
|
|
|
|
&SkipSerializingEnum::Tuple(&a, 2, 123),
|
|
|
|
&[
|
|
|
|
Token::TupleVariant {
|
|
|
|
name: "SkipSerializingEnum",
|
|
|
|
variant: "Tuple",
|
2018-05-08 13:49:37 -05:00
|
|
|
len: 1,
|
2018-05-08 13:37:52 -05:00
|
|
|
},
|
|
|
|
Token::I8(1),
|
|
|
|
Token::TupleVariantEnd,
|
|
|
|
],
|
|
|
|
);
|
2015-09-07 18:44:56 -05:00
|
|
|
}
|
2016-02-15 19:39:46 -06:00
|
|
|
|
feat(codegen): Inhibit generic bounds if skip_serializing
The generated code for a struct like:
struct Test<A, B, C> {
a: X<A>
#[serde(skip_serializing)]
b: B
#[serde(serialize_with="...")]
c: C
}
Used to be:
impl<A, B, C> Serialize for Test<A, B, C>
where A: Serialize,
B: Serialize,
C: Serialize,
{ ... }
Now it is:
impl<A, B, C> Serialize for Test<A, B, C>
where X<A>: Serialize,
{ ... }
Both `skip_serializing` and `serialize_with` mean the type does not need to
implement `Serialize`.
2016-02-28 14:17:29 -06:00
|
|
|
#[derive(Debug, PartialEq)]
|
|
|
|
struct NotSerializeStruct(i8);
|
|
|
|
|
|
|
|
#[derive(Debug, PartialEq)]
|
2017-04-13 14:28:23 -05:00
|
|
|
enum NotSerializeEnum {
|
|
|
|
Trouble,
|
|
|
|
}
|
feat(codegen): Inhibit generic bounds if skip_serializing
The generated code for a struct like:
struct Test<A, B, C> {
a: X<A>
#[serde(skip_serializing)]
b: B
#[serde(serialize_with="...")]
c: C
}
Used to be:
impl<A, B, C> Serialize for Test<A, B, C>
where A: Serialize,
B: Serialize,
C: Serialize,
{ ... }
Now it is:
impl<A, B, C> Serialize for Test<A, B, C>
where X<A>: Serialize,
{ ... }
Both `skip_serializing` and `serialize_with` mean the type does not need to
implement `Serialize`.
2016-02-28 14:17:29 -06:00
|
|
|
|
|
|
|
impl SerializeWith for NotSerializeEnum {
|
2017-01-14 18:07:43 -06:00
|
|
|
fn serialize_with<S>(&self, ser: S) -> Result<S::Ok, S::Error>
|
2017-04-13 14:28:23 -05:00
|
|
|
where
|
|
|
|
S: Serializer,
|
feat(codegen): Inhibit generic bounds if skip_serializing
The generated code for a struct like:
struct Test<A, B, C> {
a: X<A>
#[serde(skip_serializing)]
b: B
#[serde(serialize_with="...")]
c: C
}
Used to be:
impl<A, B, C> Serialize for Test<A, B, C>
where A: Serialize,
B: Serialize,
C: Serialize,
{ ... }
Now it is:
impl<A, B, C> Serialize for Test<A, B, C>
where X<A>: Serialize,
{ ... }
Both `skip_serializing` and `serialize_with` mean the type does not need to
implement `Serialize`.
2016-02-28 14:17:29 -06:00
|
|
|
{
|
|
|
|
"trouble".serialize(ser)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Debug, PartialEq, Serialize)]
|
2017-04-13 14:28:23 -05:00
|
|
|
struct ContainsNotSerialize<'a, B, C, D>
|
|
|
|
where
|
|
|
|
B: 'a,
|
|
|
|
D: SerializeWith,
|
|
|
|
{
|
feat(codegen): Inhibit generic bounds if skip_serializing
The generated code for a struct like:
struct Test<A, B, C> {
a: X<A>
#[serde(skip_serializing)]
b: B
#[serde(serialize_with="...")]
c: C
}
Used to be:
impl<A, B, C> Serialize for Test<A, B, C>
where A: Serialize,
B: Serialize,
C: Serialize,
{ ... }
Now it is:
impl<A, B, C> Serialize for Test<A, B, C>
where X<A>: Serialize,
{ ... }
Both `skip_serializing` and `serialize_with` mean the type does not need to
implement `Serialize`.
2016-02-28 14:17:29 -06:00
|
|
|
a: &'a Option<i8>,
|
2017-12-23 22:24:57 -06:00
|
|
|
#[serde(skip_serializing)]
|
|
|
|
b: &'a B,
|
|
|
|
#[serde(skip_serializing)]
|
|
|
|
c: Option<C>,
|
|
|
|
#[serde(serialize_with = "SerializeWith::serialize_with")]
|
|
|
|
d: D,
|
feat(codegen): Inhibit generic bounds if skip_serializing
The generated code for a struct like:
struct Test<A, B, C> {
a: X<A>
#[serde(skip_serializing)]
b: B
#[serde(serialize_with="...")]
c: C
}
Used to be:
impl<A, B, C> Serialize for Test<A, B, C>
where A: Serialize,
B: Serialize,
C: Serialize,
{ ... }
Now it is:
impl<A, B, C> Serialize for Test<A, B, C>
where X<A>: Serialize,
{ ... }
Both `skip_serializing` and `serialize_with` mean the type does not need to
implement `Serialize`.
2016-02-28 14:17:29 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_elt_not_serialize() {
|
|
|
|
let a = 1;
|
|
|
|
assert_ser_tokens(
|
|
|
|
&ContainsNotSerialize {
|
2017-12-23 22:13:08 -06:00
|
|
|
a: &Some(a),
|
|
|
|
b: &NotSerializeStruct(2),
|
|
|
|
c: Some(NotSerializeEnum::Trouble),
|
|
|
|
d: NotSerializeEnum::Trouble,
|
|
|
|
},
|
feat(codegen): Inhibit generic bounds if skip_serializing
The generated code for a struct like:
struct Test<A, B, C> {
a: X<A>
#[serde(skip_serializing)]
b: B
#[serde(serialize_with="...")]
c: C
}
Used to be:
impl<A, B, C> Serialize for Test<A, B, C>
where A: Serialize,
B: Serialize,
C: Serialize,
{ ... }
Now it is:
impl<A, B, C> Serialize for Test<A, B, C>
where X<A>: Serialize,
{ ... }
Both `skip_serializing` and `serialize_with` mean the type does not need to
implement `Serialize`.
2016-02-28 14:17:29 -06:00
|
|
|
&[
|
2017-12-23 22:13:08 -06:00
|
|
|
Token::Struct {
|
|
|
|
name: "ContainsNotSerialize",
|
|
|
|
len: 2,
|
|
|
|
},
|
feat(codegen): Inhibit generic bounds if skip_serializing
The generated code for a struct like:
struct Test<A, B, C> {
a: X<A>
#[serde(skip_serializing)]
b: B
#[serde(serialize_with="...")]
c: C
}
Used to be:
impl<A, B, C> Serialize for Test<A, B, C>
where A: Serialize,
B: Serialize,
C: Serialize,
{ ... }
Now it is:
impl<A, B, C> Serialize for Test<A, B, C>
where X<A>: Serialize,
{ ... }
Both `skip_serializing` and `serialize_with` mean the type does not need to
implement `Serialize`.
2016-02-28 14:17:29 -06:00
|
|
|
Token::Str("a"),
|
2017-04-05 12:40:14 -05:00
|
|
|
Token::Some,
|
feat(codegen): Inhibit generic bounds if skip_serializing
The generated code for a struct like:
struct Test<A, B, C> {
a: X<A>
#[serde(skip_serializing)]
b: B
#[serde(serialize_with="...")]
c: C
}
Used to be:
impl<A, B, C> Serialize for Test<A, B, C>
where A: Serialize,
B: Serialize,
C: Serialize,
{ ... }
Now it is:
impl<A, B, C> Serialize for Test<A, B, C>
where X<A>: Serialize,
{ ... }
Both `skip_serializing` and `serialize_with` mean the type does not need to
implement `Serialize`.
2016-02-28 14:17:29 -06:00
|
|
|
Token::I8(1),
|
|
|
|
Token::Str("d"),
|
|
|
|
Token::Str("trouble"),
|
|
|
|
Token::StructEnd,
|
2017-04-13 14:28:23 -05:00
|
|
|
],
|
feat(codegen): Inhibit generic bounds if skip_serializing
The generated code for a struct like:
struct Test<A, B, C> {
a: X<A>
#[serde(skip_serializing)]
b: B
#[serde(serialize_with="...")]
c: C
}
Used to be:
impl<A, B, C> Serialize for Test<A, B, C>
where A: Serialize,
B: Serialize,
C: Serialize,
{ ... }
Now it is:
impl<A, B, C> Serialize for Test<A, B, C>
where X<A>: Serialize,
{ ... }
Both `skip_serializing` and `serialize_with` mean the type does not need to
implement `Serialize`.
2016-02-28 14:17:29 -06:00
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2016-02-15 19:39:46 -06:00
|
|
|
#[derive(Debug, PartialEq, Serialize)]
|
2017-04-13 14:28:23 -05:00
|
|
|
struct SerializeWithStruct<'a, B>
|
|
|
|
where
|
|
|
|
B: SerializeWith,
|
|
|
|
{
|
2016-02-15 19:39:46 -06:00
|
|
|
a: &'a i8,
|
2017-12-23 22:24:57 -06:00
|
|
|
#[serde(serialize_with = "SerializeWith::serialize_with")]
|
|
|
|
b: B,
|
2016-02-15 19:39:46 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_serialize_with_struct() {
|
|
|
|
let a = 1;
|
|
|
|
assert_ser_tokens(
|
2017-04-13 14:28:23 -05:00
|
|
|
&SerializeWithStruct { a: &a, b: 2 },
|
2016-02-15 19:39:46 -06:00
|
|
|
&[
|
2017-12-23 22:13:08 -06:00
|
|
|
Token::Struct {
|
|
|
|
name: "SerializeWithStruct",
|
|
|
|
len: 2,
|
|
|
|
},
|
2016-02-15 19:39:46 -06:00
|
|
|
Token::Str("a"),
|
|
|
|
Token::I8(1),
|
|
|
|
Token::Str("b"),
|
|
|
|
Token::Bool(false),
|
|
|
|
Token::StructEnd,
|
2017-04-13 14:28:23 -05:00
|
|
|
],
|
2016-02-15 19:39:46 -06:00
|
|
|
);
|
|
|
|
|
|
|
|
assert_ser_tokens(
|
2017-04-13 14:28:23 -05:00
|
|
|
&SerializeWithStruct { a: &a, b: 123 },
|
2016-02-15 19:39:46 -06:00
|
|
|
&[
|
2017-12-23 22:13:08 -06:00
|
|
|
Token::Struct {
|
|
|
|
name: "SerializeWithStruct",
|
|
|
|
len: 2,
|
|
|
|
},
|
2016-02-15 19:39:46 -06:00
|
|
|
Token::Str("a"),
|
|
|
|
Token::I8(1),
|
|
|
|
Token::Str("b"),
|
|
|
|
Token::Bool(true),
|
|
|
|
Token::StructEnd,
|
2017-04-13 14:28:23 -05:00
|
|
|
],
|
2016-02-15 19:39:46 -06:00
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Debug, PartialEq, Serialize)]
|
2017-04-13 14:28:23 -05:00
|
|
|
enum SerializeWithEnum<'a, B>
|
|
|
|
where
|
|
|
|
B: SerializeWith,
|
|
|
|
{
|
2016-02-15 19:39:46 -06:00
|
|
|
Struct {
|
|
|
|
a: &'a i8,
|
2017-12-23 22:24:57 -06:00
|
|
|
#[serde(serialize_with = "SerializeWith::serialize_with")]
|
|
|
|
b: B,
|
2017-04-13 14:28:23 -05:00
|
|
|
},
|
2016-02-15 19:39:46 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_serialize_with_enum() {
|
|
|
|
let a = 1;
|
|
|
|
assert_ser_tokens(
|
2017-04-13 14:28:23 -05:00
|
|
|
&SerializeWithEnum::Struct { a: &a, b: 2 },
|
2016-02-15 19:39:46 -06:00
|
|
|
&[
|
2017-12-23 22:13:08 -06:00
|
|
|
Token::StructVariant {
|
|
|
|
name: "SerializeWithEnum",
|
|
|
|
variant: "Struct",
|
|
|
|
len: 2,
|
|
|
|
},
|
2016-02-15 19:39:46 -06:00
|
|
|
Token::Str("a"),
|
|
|
|
Token::I8(1),
|
|
|
|
Token::Str("b"),
|
|
|
|
Token::Bool(false),
|
2017-04-05 12:40:14 -05:00
|
|
|
Token::StructVariantEnd,
|
2017-04-13 14:28:23 -05:00
|
|
|
],
|
2016-02-15 19:39:46 -06:00
|
|
|
);
|
|
|
|
|
|
|
|
assert_ser_tokens(
|
2017-04-13 14:28:23 -05:00
|
|
|
&SerializeWithEnum::Struct { a: &a, b: 123 },
|
2016-02-15 19:39:46 -06:00
|
|
|
&[
|
2017-12-23 22:13:08 -06:00
|
|
|
Token::StructVariant {
|
|
|
|
name: "SerializeWithEnum",
|
|
|
|
variant: "Struct",
|
|
|
|
len: 2,
|
|
|
|
},
|
2016-02-15 19:39:46 -06:00
|
|
|
Token::Str("a"),
|
|
|
|
Token::I8(1),
|
|
|
|
Token::Str("b"),
|
|
|
|
Token::Bool(true),
|
2017-04-05 12:40:14 -05:00
|
|
|
Token::StructVariantEnd,
|
2017-04-13 14:28:23 -05:00
|
|
|
],
|
2016-02-15 19:39:46 -06:00
|
|
|
);
|
|
|
|
}
|
2016-02-15 22:43:11 -06:00
|
|
|
|
2017-08-14 16:39:29 -05:00
|
|
|
#[derive(Debug, PartialEq, Serialize, Deserialize)]
|
|
|
|
enum WithVariant {
|
2017-12-23 22:13:08 -06:00
|
|
|
#[serde(serialize_with = "serialize_unit_variant_as_i8")]
|
|
|
|
#[serde(deserialize_with = "deserialize_i8_as_unit_variant")]
|
2017-08-07 19:22:26 -05:00
|
|
|
Unit,
|
|
|
|
|
2017-12-23 22:13:08 -06:00
|
|
|
#[serde(serialize_with = "SerializeWith::serialize_with")]
|
|
|
|
#[serde(deserialize_with = "DeserializeWith::deserialize_with")]
|
2017-08-07 19:22:26 -05:00
|
|
|
Newtype(i32),
|
|
|
|
|
2017-12-23 22:13:08 -06:00
|
|
|
#[serde(serialize_with = "serialize_variant_as_string")]
|
|
|
|
#[serde(deserialize_with = "deserialize_string_as_variant")]
|
2017-08-07 19:22:26 -05:00
|
|
|
Tuple(String, u8),
|
|
|
|
|
2017-12-23 22:13:08 -06:00
|
|
|
#[serde(serialize_with = "serialize_variant_as_string")]
|
|
|
|
#[serde(deserialize_with = "deserialize_string_as_variant")]
|
|
|
|
Struct { f1: String, f2: u8 },
|
2017-08-07 19:22:26 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
fn serialize_unit_variant_as_i8<S>(serializer: S) -> Result<S::Ok, S::Error>
|
2017-12-23 22:13:08 -06:00
|
|
|
where
|
|
|
|
S: Serializer,
|
2017-08-07 19:22:26 -05:00
|
|
|
{
|
|
|
|
serializer.serialize_i8(0)
|
|
|
|
}
|
|
|
|
|
2017-08-14 16:39:29 -05:00
|
|
|
fn deserialize_i8_as_unit_variant<'de, D>(deserializer: D) -> Result<(), D::Error>
|
2017-12-23 22:13:08 -06:00
|
|
|
where
|
|
|
|
D: Deserializer<'de>,
|
2017-08-14 16:39:29 -05:00
|
|
|
{
|
|
|
|
let n = i8::deserialize(deserializer)?;
|
|
|
|
match n {
|
|
|
|
0 => Ok(()),
|
|
|
|
_ => Err(de::Error::invalid_value(Unexpected::Signed(n as i64), &"0")),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-12-23 22:13:08 -06:00
|
|
|
fn serialize_variant_as_string<S>(f1: &str, f2: &u8, serializer: S) -> Result<S::Ok, S::Error>
|
|
|
|
where
|
|
|
|
S: Serializer,
|
2017-08-07 19:22:26 -05:00
|
|
|
{
|
2023-02-02 13:04:18 -06:00
|
|
|
serializer.collect_str(&format_args!("{};{:?}", f1, f2))
|
2017-08-07 19:22:26 -05:00
|
|
|
}
|
|
|
|
|
2017-08-14 16:39:29 -05:00
|
|
|
fn deserialize_string_as_variant<'de, D>(deserializer: D) -> Result<(String, u8), D::Error>
|
2017-12-23 22:13:08 -06:00
|
|
|
where
|
|
|
|
D: Deserializer<'de>,
|
2017-08-14 16:39:29 -05:00
|
|
|
{
|
|
|
|
let s = String::deserialize(deserializer)?;
|
|
|
|
let mut pieces = s.split(';');
|
Resolve manual_let_else clippy lints
error: this could be rewritten as `let...else`
--> test_suite/tests/test_annotations.rs:1247:5
|
1247 | / let f1 = match pieces.next() {
1248 | | Some(x) => x,
1249 | | None => return Err(de::Error::invalid_length(0, &"2")),
1250 | | };
| |______^ help: consider writing: `let Some(x) = pieces.next() else { return Err(de::Error::invalid_length(0, &"2")) };`
|
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#manual_let_else
= note: `-D clippy::manual-let-else` implied by `-D clippy::pedantic`
error: this could be rewritten as `let...else`
--> test_suite/tests/test_annotations.rs:1251:5
|
1251 | / let f2 = match pieces.next() {
1252 | | Some(x) => x,
1253 | | None => return Err(de::Error::invalid_length(1, &"2")),
1254 | | };
| |______^ help: consider writing: `let Some(x) = pieces.next() else { return Err(de::Error::invalid_length(1, &"2")) };`
|
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#manual_let_else
error: this could be rewritten as `let...else`
--> test_suite/tests/test_annotations.rs:1255:5
|
1255 | / let f2 = match f2.parse() {
1256 | | Ok(n) => n,
1257 | | Err(_) => {
1258 | | return Err(de::Error::invalid_value(
... |
1262 | | }
1263 | | };
| |______^
|
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#manual_let_else
help: consider writing
|
1255 ~ let Ok(n) = f2.parse() else {
1256 + return Err(de::Error::invalid_value(
1257 + Unexpected::Str(f2),
1258 + &"an 8-bit signed integer",
1259 + ));
1260 + };
|
2022-11-22 20:44:48 -06:00
|
|
|
let Some(f1) = pieces.next() else {
|
|
|
|
return Err(de::Error::invalid_length(0, &"2"));
|
2017-08-14 16:39:29 -05:00
|
|
|
};
|
Resolve manual_let_else clippy lints
error: this could be rewritten as `let...else`
--> test_suite/tests/test_annotations.rs:1247:5
|
1247 | / let f1 = match pieces.next() {
1248 | | Some(x) => x,
1249 | | None => return Err(de::Error::invalid_length(0, &"2")),
1250 | | };
| |______^ help: consider writing: `let Some(x) = pieces.next() else { return Err(de::Error::invalid_length(0, &"2")) };`
|
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#manual_let_else
= note: `-D clippy::manual-let-else` implied by `-D clippy::pedantic`
error: this could be rewritten as `let...else`
--> test_suite/tests/test_annotations.rs:1251:5
|
1251 | / let f2 = match pieces.next() {
1252 | | Some(x) => x,
1253 | | None => return Err(de::Error::invalid_length(1, &"2")),
1254 | | };
| |______^ help: consider writing: `let Some(x) = pieces.next() else { return Err(de::Error::invalid_length(1, &"2")) };`
|
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#manual_let_else
error: this could be rewritten as `let...else`
--> test_suite/tests/test_annotations.rs:1255:5
|
1255 | / let f2 = match f2.parse() {
1256 | | Ok(n) => n,
1257 | | Err(_) => {
1258 | | return Err(de::Error::invalid_value(
... |
1262 | | }
1263 | | };
| |______^
|
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#manual_let_else
help: consider writing
|
1255 ~ let Ok(n) = f2.parse() else {
1256 + return Err(de::Error::invalid_value(
1257 + Unexpected::Str(f2),
1258 + &"an 8-bit signed integer",
1259 + ));
1260 + };
|
2022-11-22 20:44:48 -06:00
|
|
|
let Some(f2) = pieces.next() else {
|
|
|
|
return Err(de::Error::invalid_length(1, &"2"));
|
2017-08-14 16:39:29 -05:00
|
|
|
};
|
Resolve manual_let_else clippy lints
error: this could be rewritten as `let...else`
--> test_suite/tests/test_annotations.rs:1247:5
|
1247 | / let f1 = match pieces.next() {
1248 | | Some(x) => x,
1249 | | None => return Err(de::Error::invalid_length(0, &"2")),
1250 | | };
| |______^ help: consider writing: `let Some(x) = pieces.next() else { return Err(de::Error::invalid_length(0, &"2")) };`
|
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#manual_let_else
= note: `-D clippy::manual-let-else` implied by `-D clippy::pedantic`
error: this could be rewritten as `let...else`
--> test_suite/tests/test_annotations.rs:1251:5
|
1251 | / let f2 = match pieces.next() {
1252 | | Some(x) => x,
1253 | | None => return Err(de::Error::invalid_length(1, &"2")),
1254 | | };
| |______^ help: consider writing: `let Some(x) = pieces.next() else { return Err(de::Error::invalid_length(1, &"2")) };`
|
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#manual_let_else
error: this could be rewritten as `let...else`
--> test_suite/tests/test_annotations.rs:1255:5
|
1255 | / let f2 = match f2.parse() {
1256 | | Ok(n) => n,
1257 | | Err(_) => {
1258 | | return Err(de::Error::invalid_value(
... |
1262 | | }
1263 | | };
| |______^
|
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#manual_let_else
help: consider writing
|
1255 ~ let Ok(n) = f2.parse() else {
1256 + return Err(de::Error::invalid_value(
1257 + Unexpected::Str(f2),
1258 + &"an 8-bit signed integer",
1259 + ));
1260 + };
|
2022-11-22 20:44:48 -06:00
|
|
|
let Ok(f2) = f2.parse() else {
|
|
|
|
return Err(de::Error::invalid_value(
|
|
|
|
Unexpected::Str(f2),
|
|
|
|
&"an 8-bit signed integer",
|
|
|
|
));
|
2017-08-14 16:39:29 -05:00
|
|
|
};
|
|
|
|
Ok((f1.into(), f2))
|
|
|
|
}
|
|
|
|
|
2017-08-07 19:22:26 -05:00
|
|
|
#[test]
|
|
|
|
fn test_serialize_with_variant() {
|
|
|
|
assert_ser_tokens(
|
2017-08-14 16:39:29 -05:00
|
|
|
&WithVariant::Unit,
|
2017-08-07 19:22:26 -05:00
|
|
|
&[
|
2017-12-23 22:13:08 -06:00
|
|
|
Token::NewtypeVariant {
|
|
|
|
name: "WithVariant",
|
|
|
|
variant: "Unit",
|
|
|
|
},
|
2017-08-07 19:22:26 -05:00
|
|
|
Token::I8(0),
|
|
|
|
],
|
|
|
|
);
|
|
|
|
|
|
|
|
assert_ser_tokens(
|
2017-08-14 16:39:29 -05:00
|
|
|
&WithVariant::Newtype(123),
|
2017-08-07 19:22:26 -05:00
|
|
|
&[
|
2017-12-23 22:13:08 -06:00
|
|
|
Token::NewtypeVariant {
|
|
|
|
name: "WithVariant",
|
|
|
|
variant: "Newtype",
|
|
|
|
},
|
2017-08-07 19:22:26 -05:00
|
|
|
Token::Bool(true),
|
|
|
|
],
|
|
|
|
);
|
|
|
|
|
|
|
|
assert_ser_tokens(
|
2017-08-14 16:39:29 -05:00
|
|
|
&WithVariant::Tuple("hello".into(), 0),
|
2017-08-07 19:22:26 -05:00
|
|
|
&[
|
2017-12-23 22:13:08 -06:00
|
|
|
Token::NewtypeVariant {
|
|
|
|
name: "WithVariant",
|
|
|
|
variant: "Tuple",
|
|
|
|
},
|
2017-08-07 19:22:26 -05:00
|
|
|
Token::Str("hello;0"),
|
|
|
|
],
|
|
|
|
);
|
|
|
|
|
|
|
|
assert_ser_tokens(
|
2017-12-23 22:13:08 -06:00
|
|
|
&WithVariant::Struct {
|
|
|
|
f1: "world".into(),
|
|
|
|
f2: 1,
|
|
|
|
},
|
2017-08-14 16:39:29 -05:00
|
|
|
&[
|
2017-12-23 22:13:08 -06:00
|
|
|
Token::NewtypeVariant {
|
|
|
|
name: "WithVariant",
|
|
|
|
variant: "Struct",
|
|
|
|
},
|
2017-08-14 16:39:29 -05:00
|
|
|
Token::Str("world;1"),
|
|
|
|
],
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_deserialize_with_variant() {
|
|
|
|
assert_de_tokens(
|
|
|
|
&WithVariant::Unit,
|
|
|
|
&[
|
2017-12-23 22:13:08 -06:00
|
|
|
Token::NewtypeVariant {
|
|
|
|
name: "WithVariant",
|
|
|
|
variant: "Unit",
|
|
|
|
},
|
2017-08-14 16:39:29 -05:00
|
|
|
Token::I8(0),
|
|
|
|
],
|
|
|
|
);
|
|
|
|
|
|
|
|
assert_de_tokens(
|
|
|
|
&WithVariant::Newtype(123),
|
|
|
|
&[
|
2017-12-23 22:13:08 -06:00
|
|
|
Token::NewtypeVariant {
|
|
|
|
name: "WithVariant",
|
|
|
|
variant: "Newtype",
|
|
|
|
},
|
2017-08-14 16:39:29 -05:00
|
|
|
Token::Bool(true),
|
|
|
|
],
|
|
|
|
);
|
|
|
|
|
|
|
|
assert_de_tokens(
|
|
|
|
&WithVariant::Tuple("hello".into(), 0),
|
|
|
|
&[
|
2017-12-23 22:13:08 -06:00
|
|
|
Token::NewtypeVariant {
|
|
|
|
name: "WithVariant",
|
|
|
|
variant: "Tuple",
|
|
|
|
},
|
2017-08-14 16:39:29 -05:00
|
|
|
Token::Str("hello;0"),
|
|
|
|
],
|
|
|
|
);
|
|
|
|
|
|
|
|
assert_de_tokens(
|
2017-12-23 22:13:08 -06:00
|
|
|
&WithVariant::Struct {
|
|
|
|
f1: "world".into(),
|
|
|
|
f2: 1,
|
|
|
|
},
|
2017-08-07 19:22:26 -05:00
|
|
|
&[
|
2017-12-23 22:13:08 -06:00
|
|
|
Token::NewtypeVariant {
|
|
|
|
name: "WithVariant",
|
|
|
|
variant: "Struct",
|
|
|
|
},
|
2017-08-07 19:22:26 -05:00
|
|
|
Token::Str("world;1"),
|
|
|
|
],
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2016-02-15 22:43:11 -06:00
|
|
|
#[derive(Debug, PartialEq, Deserialize)]
|
2017-04-13 14:28:23 -05:00
|
|
|
struct DeserializeWithStruct<B>
|
|
|
|
where
|
|
|
|
B: DeserializeWith,
|
|
|
|
{
|
2016-02-15 22:43:11 -06:00
|
|
|
a: i8,
|
2017-12-23 22:24:57 -06:00
|
|
|
#[serde(deserialize_with = "DeserializeWith::deserialize_with")]
|
|
|
|
b: B,
|
2016-02-15 22:43:11 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_deserialize_with_struct() {
|
|
|
|
assert_de_tokens(
|
2017-04-13 14:28:23 -05:00
|
|
|
&DeserializeWithStruct { a: 1, b: 2 },
|
2016-06-29 01:50:19 -05:00
|
|
|
&[
|
2017-12-23 22:13:08 -06:00
|
|
|
Token::Struct {
|
|
|
|
name: "DeserializeWithStruct",
|
|
|
|
len: 2,
|
|
|
|
},
|
2016-02-15 22:43:11 -06:00
|
|
|
Token::Str("a"),
|
|
|
|
Token::I8(1),
|
|
|
|
Token::Str("b"),
|
|
|
|
Token::Bool(false),
|
|
|
|
Token::StructEnd,
|
2017-04-13 14:28:23 -05:00
|
|
|
],
|
2016-02-15 22:43:11 -06:00
|
|
|
);
|
|
|
|
|
|
|
|
assert_de_tokens(
|
2017-04-13 14:28:23 -05:00
|
|
|
&DeserializeWithStruct { a: 1, b: 123 },
|
2016-06-29 01:50:19 -05:00
|
|
|
&[
|
2017-12-23 22:13:08 -06:00
|
|
|
Token::Struct {
|
|
|
|
name: "DeserializeWithStruct",
|
|
|
|
len: 2,
|
|
|
|
},
|
2016-02-15 22:43:11 -06:00
|
|
|
Token::Str("a"),
|
|
|
|
Token::I8(1),
|
|
|
|
Token::Str("b"),
|
|
|
|
Token::Bool(true),
|
|
|
|
Token::StructEnd,
|
2017-04-13 14:28:23 -05:00
|
|
|
],
|
2016-02-15 22:43:11 -06:00
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Debug, PartialEq, Deserialize)]
|
2017-04-13 14:28:23 -05:00
|
|
|
enum DeserializeWithEnum<B>
|
|
|
|
where
|
|
|
|
B: DeserializeWith,
|
|
|
|
{
|
2016-02-15 22:43:11 -06:00
|
|
|
Struct {
|
|
|
|
a: i8,
|
2017-12-23 22:24:57 -06:00
|
|
|
#[serde(deserialize_with = "DeserializeWith::deserialize_with")]
|
|
|
|
b: B,
|
2017-04-13 14:28:23 -05:00
|
|
|
},
|
2016-02-15 22:43:11 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_deserialize_with_enum() {
|
|
|
|
assert_de_tokens(
|
2017-04-13 14:28:23 -05:00
|
|
|
&DeserializeWithEnum::Struct { a: 1, b: 2 },
|
2016-06-29 01:50:19 -05:00
|
|
|
&[
|
2017-12-23 22:13:08 -06:00
|
|
|
Token::StructVariant {
|
|
|
|
name: "DeserializeWithEnum",
|
|
|
|
variant: "Struct",
|
|
|
|
len: 2,
|
|
|
|
},
|
2016-02-15 22:43:11 -06:00
|
|
|
Token::Str("a"),
|
|
|
|
Token::I8(1),
|
|
|
|
Token::Str("b"),
|
|
|
|
Token::Bool(false),
|
2017-04-05 12:40:14 -05:00
|
|
|
Token::StructVariantEnd,
|
2017-04-13 14:28:23 -05:00
|
|
|
],
|
2016-02-15 22:43:11 -06:00
|
|
|
);
|
|
|
|
|
|
|
|
assert_de_tokens(
|
2017-04-13 14:28:23 -05:00
|
|
|
&DeserializeWithEnum::Struct { a: 1, b: 123 },
|
2016-06-29 01:50:19 -05:00
|
|
|
&[
|
2017-12-23 22:13:08 -06:00
|
|
|
Token::StructVariant {
|
|
|
|
name: "DeserializeWithEnum",
|
|
|
|
variant: "Struct",
|
|
|
|
len: 2,
|
|
|
|
},
|
2016-02-15 22:43:11 -06:00
|
|
|
Token::Str("a"),
|
|
|
|
Token::I8(1),
|
|
|
|
Token::Str("b"),
|
|
|
|
Token::Bool(true),
|
2017-04-05 12:40:14 -05:00
|
|
|
Token::StructVariantEnd,
|
2017-04-13 14:28:23 -05:00
|
|
|
],
|
2016-02-15 22:43:11 -06:00
|
|
|
);
|
|
|
|
}
|
2016-04-12 05:42:07 -05:00
|
|
|
|
|
|
|
#[test]
|
2016-04-12 10:26:56 -05:00
|
|
|
fn test_missing_renamed_field_struct() {
|
2016-04-12 05:42:07 -05:00
|
|
|
assert_de_tokens_error::<RenameStruct>(
|
2016-06-29 01:50:19 -05:00
|
|
|
&[
|
2017-12-23 22:13:08 -06:00
|
|
|
Token::Struct {
|
|
|
|
name: "Superhero",
|
|
|
|
len: 2,
|
|
|
|
},
|
2016-04-12 05:42:07 -05:00
|
|
|
Token::Str("a1"),
|
|
|
|
Token::I32(1),
|
|
|
|
Token::StructEnd,
|
|
|
|
],
|
2017-04-19 13:38:57 -05:00
|
|
|
"missing field `a3`",
|
2016-04-12 10:26:56 -05:00
|
|
|
);
|
|
|
|
|
|
|
|
assert_de_tokens_error::<RenameStructSerializeDeserialize>(
|
2016-06-29 01:50:19 -05:00
|
|
|
&[
|
2017-12-23 22:13:08 -06:00
|
|
|
Token::Struct {
|
|
|
|
name: "SuperheroDe",
|
|
|
|
len: 2,
|
|
|
|
},
|
2016-04-12 10:26:56 -05:00
|
|
|
Token::Str("a1"),
|
|
|
|
Token::I32(1),
|
|
|
|
Token::StructEnd,
|
|
|
|
],
|
2017-04-19 13:38:57 -05:00
|
|
|
"missing field `a5`",
|
2016-04-12 10:26:56 -05:00
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_missing_renamed_field_enum() {
|
|
|
|
assert_de_tokens_error::<RenameEnum>(
|
2016-06-29 01:50:19 -05:00
|
|
|
&[
|
2017-12-23 22:13:08 -06:00
|
|
|
Token::StructVariant {
|
|
|
|
name: "Superhero",
|
|
|
|
variant: "barry_allan",
|
|
|
|
len: 1,
|
|
|
|
},
|
2017-04-05 12:40:14 -05:00
|
|
|
Token::StructVariantEnd,
|
2016-04-12 10:26:56 -05:00
|
|
|
],
|
2017-04-19 13:38:57 -05:00
|
|
|
"missing field `b`",
|
2016-04-12 10:26:56 -05:00
|
|
|
);
|
|
|
|
|
|
|
|
assert_de_tokens_error::<RenameEnumSerializeDeserialize<i8>>(
|
2016-06-29 01:50:19 -05:00
|
|
|
&[
|
2017-12-23 22:13:08 -06:00
|
|
|
Token::StructVariant {
|
|
|
|
name: "SuperheroDe",
|
|
|
|
variant: "jason_todd",
|
|
|
|
len: 2,
|
|
|
|
},
|
2016-04-12 10:26:56 -05:00
|
|
|
Token::Str("a"),
|
|
|
|
Token::I8(0),
|
2017-04-05 12:40:14 -05:00
|
|
|
Token::StructVariantEnd,
|
2016-04-12 10:26:56 -05:00
|
|
|
],
|
2017-04-19 13:38:57 -05:00
|
|
|
"missing field `d`",
|
2016-04-12 10:26:56 -05:00
|
|
|
);
|
2016-04-12 05:42:07 -05:00
|
|
|
}
|
2016-07-05 02:52:19 -05:00
|
|
|
|
|
|
|
#[derive(Debug, PartialEq, Deserialize)]
|
|
|
|
enum InvalidLengthEnum {
|
|
|
|
A(i32, i32, i32),
|
2018-04-30 03:41:22 -05:00
|
|
|
B(#[serde(skip_deserializing)] i32, i32, i32),
|
2016-07-05 02:52:19 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_invalid_length_enum() {
|
|
|
|
assert_de_tokens_error::<InvalidLengthEnum>(
|
|
|
|
&[
|
2017-12-23 22:13:08 -06:00
|
|
|
Token::TupleVariant {
|
|
|
|
name: "InvalidLengthEnum",
|
|
|
|
variant: "A",
|
|
|
|
len: 3,
|
|
|
|
},
|
2017-04-05 11:42:24 -05:00
|
|
|
Token::I32(1),
|
2017-04-05 12:40:14 -05:00
|
|
|
Token::TupleVariantEnd,
|
2016-07-05 02:52:19 -05:00
|
|
|
],
|
2018-05-08 14:03:35 -05:00
|
|
|
"invalid length 1, expected tuple variant InvalidLengthEnum::A with 3 elements",
|
2016-07-05 02:52:19 -05:00
|
|
|
);
|
|
|
|
assert_de_tokens_error::<InvalidLengthEnum>(
|
|
|
|
&[
|
2017-12-23 22:13:08 -06:00
|
|
|
Token::TupleVariant {
|
|
|
|
name: "InvalidLengthEnum",
|
|
|
|
variant: "B",
|
2023-05-27 07:17:00 -05:00
|
|
|
len: 2,
|
2017-12-23 22:13:08 -06:00
|
|
|
},
|
2017-04-05 11:42:24 -05:00
|
|
|
Token::I32(1),
|
2017-04-05 12:40:14 -05:00
|
|
|
Token::TupleVariantEnd,
|
2016-07-05 02:52:19 -05:00
|
|
|
],
|
2018-05-08 14:03:35 -05:00
|
|
|
"invalid length 1, expected tuple variant InvalidLengthEnum::B with 2 elements",
|
2016-07-05 02:52:19 -05:00
|
|
|
);
|
|
|
|
}
|
2017-03-18 11:22:27 -05:00
|
|
|
|
|
|
|
#[derive(Clone, Serialize, Deserialize, PartialEq, Debug)]
|
2017-12-23 22:13:08 -06:00
|
|
|
#[serde(into = "EnumToU32", from = "EnumToU32")]
|
2017-03-18 11:22:27 -05:00
|
|
|
struct StructFromEnum(Option<u32>);
|
|
|
|
|
|
|
|
impl Into<EnumToU32> for StructFromEnum {
|
|
|
|
fn into(self) -> EnumToU32 {
|
|
|
|
match self {
|
2017-04-13 14:28:23 -05:00
|
|
|
StructFromEnum(v) => v.into(),
|
2017-03-18 11:22:27 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl From<EnumToU32> for StructFromEnum {
|
|
|
|
fn from(v: EnumToU32) -> Self {
|
|
|
|
StructFromEnum(v.into())
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Clone, Serialize, Deserialize, PartialEq, Debug)]
|
2017-12-23 22:13:08 -06:00
|
|
|
#[serde(into = "Option<u32>", from = "Option<u32>")]
|
2017-03-18 11:22:27 -05:00
|
|
|
enum EnumToU32 {
|
|
|
|
One,
|
|
|
|
Two,
|
|
|
|
Three,
|
|
|
|
Four,
|
2017-04-13 14:28:23 -05:00
|
|
|
Nothing,
|
2017-03-18 11:22:27 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
impl Into<Option<u32>> for EnumToU32 {
|
|
|
|
fn into(self) -> Option<u32> {
|
|
|
|
match self {
|
|
|
|
EnumToU32::One => Some(1),
|
|
|
|
EnumToU32::Two => Some(2),
|
|
|
|
EnumToU32::Three => Some(3),
|
|
|
|
EnumToU32::Four => Some(4),
|
2017-04-13 14:28:23 -05:00
|
|
|
EnumToU32::Nothing => None,
|
2017-03-18 11:22:27 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl From<Option<u32>> for EnumToU32 {
|
|
|
|
fn from(v: Option<u32>) -> Self {
|
|
|
|
match v {
|
|
|
|
Some(1) => EnumToU32::One,
|
|
|
|
Some(2) => EnumToU32::Two,
|
|
|
|
Some(3) => EnumToU32::Three,
|
|
|
|
Some(4) => EnumToU32::Four,
|
2017-04-13 14:28:23 -05:00
|
|
|
_ => EnumToU32::Nothing,
|
2017-03-18 11:22:27 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-05-12 01:26:42 -05:00
|
|
|
#[derive(Clone, Deserialize, PartialEq, Debug)]
|
2019-07-17 14:30:21 -05:00
|
|
|
#[serde(try_from = "u32")]
|
|
|
|
enum TryFromU32 {
|
|
|
|
One,
|
|
|
|
Two,
|
|
|
|
}
|
2019-05-12 01:26:42 -05:00
|
|
|
|
2019-07-17 14:30:21 -05:00
|
|
|
impl TryFrom<u32> for TryFromU32 {
|
2019-05-12 01:26:42 -05:00
|
|
|
type Error = String;
|
|
|
|
|
2019-07-17 14:30:21 -05:00
|
|
|
fn try_from(value: u32) -> Result<Self, Self::Error> {
|
2019-05-12 01:26:42 -05:00
|
|
|
match value {
|
2019-07-17 14:30:21 -05:00
|
|
|
1 => Ok(TryFromU32::One),
|
|
|
|
2 => Ok(TryFromU32::Two),
|
|
|
|
_ => Err("out of range".to_owned()),
|
2019-05-12 01:26:42 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-03-18 11:22:27 -05:00
|
|
|
#[test]
|
|
|
|
fn test_from_into_traits() {
|
2019-07-17 14:32:34 -05:00
|
|
|
assert_ser_tokens(&EnumToU32::One, &[Token::Some, Token::U32(1)]);
|
|
|
|
assert_ser_tokens(&EnumToU32::Nothing, &[Token::None]);
|
|
|
|
assert_de_tokens(&EnumToU32::Two, &[Token::Some, Token::U32(2)]);
|
|
|
|
assert_ser_tokens(&StructFromEnum(Some(5)), &[Token::None]);
|
|
|
|
assert_ser_tokens(&StructFromEnum(None), &[Token::None]);
|
|
|
|
assert_de_tokens(&StructFromEnum(Some(2)), &[Token::Some, Token::U32(2)]);
|
|
|
|
assert_de_tokens(&TryFromU32::Two, &[Token::U32(2)]);
|
2019-07-17 14:30:21 -05:00
|
|
|
assert_de_tokens_error::<TryFromU32>(&[Token::U32(5)], "out of range");
|
2017-03-18 11:22:27 -05:00
|
|
|
}
|
2018-03-14 12:46:47 -05:00
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_collect_other() {
|
|
|
|
let mut extra = HashMap::new();
|
|
|
|
extra.insert("c".into(), 3);
|
2018-03-20 07:38:08 -05:00
|
|
|
assert_tokens(
|
2018-03-14 15:17:02 -05:00
|
|
|
&CollectOther { a: 1, b: 2, extra },
|
2018-03-14 12:46:47 -05:00
|
|
|
&[
|
|
|
|
Token::Map { len: None },
|
|
|
|
Token::Str("a"),
|
|
|
|
Token::U32(1),
|
|
|
|
Token::Str("b"),
|
|
|
|
Token::U32(2),
|
|
|
|
Token::Str("c"),
|
|
|
|
Token::U32(3),
|
|
|
|
Token::MapEnd,
|
|
|
|
],
|
|
|
|
);
|
|
|
|
}
|
2018-03-16 16:40:08 -05:00
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_flatten_struct_enum() {
|
|
|
|
let mut extra = HashMap::new();
|
|
|
|
extra.insert("extra_key".into(), "extra value".into());
|
2018-03-16 16:58:16 -05:00
|
|
|
let change_request = FlattenStructEnumWrapper {
|
|
|
|
data: FlattenStructEnum::InsertInteger {
|
2018-03-16 16:40:08 -05:00
|
|
|
index: 0,
|
2018-04-30 03:41:22 -05:00
|
|
|
value: 42,
|
2018-03-16 16:40:08 -05:00
|
|
|
},
|
2018-03-16 18:49:00 -05:00
|
|
|
extra,
|
2018-03-16 16:40:08 -05:00
|
|
|
};
|
|
|
|
assert_de_tokens(
|
|
|
|
&change_request,
|
|
|
|
&[
|
|
|
|
Token::Map { len: None },
|
|
|
|
Token::Str("insert_integer"),
|
|
|
|
Token::Map { len: None },
|
|
|
|
Token::Str("index"),
|
|
|
|
Token::U32(0),
|
|
|
|
Token::Str("value"),
|
|
|
|
Token::U32(42),
|
|
|
|
Token::MapEnd,
|
|
|
|
Token::Str("extra_key"),
|
2018-03-16 18:49:00 -05:00
|
|
|
Token::Str("extra value"),
|
2018-04-30 03:41:22 -05:00
|
|
|
Token::MapEnd,
|
2018-03-16 16:40:08 -05:00
|
|
|
],
|
|
|
|
);
|
|
|
|
assert_ser_tokens(
|
|
|
|
&change_request,
|
|
|
|
&[
|
|
|
|
Token::Map { len: None },
|
|
|
|
Token::Str("insert_integer"),
|
2018-04-30 03:41:22 -05:00
|
|
|
Token::Struct {
|
|
|
|
len: 2,
|
|
|
|
name: "insert_integer",
|
|
|
|
},
|
2018-03-16 16:40:08 -05:00
|
|
|
Token::Str("index"),
|
|
|
|
Token::U32(0),
|
|
|
|
Token::Str("value"),
|
|
|
|
Token::U32(42),
|
|
|
|
Token::StructEnd,
|
|
|
|
Token::Str("extra_key"),
|
2018-03-16 18:49:00 -05:00
|
|
|
Token::Str("extra value"),
|
2018-04-30 03:41:22 -05:00
|
|
|
Token::MapEnd,
|
2018-03-16 16:40:08 -05:00
|
|
|
],
|
|
|
|
);
|
|
|
|
}
|
2018-03-16 16:58:16 -05:00
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_flatten_struct_tag_content_enum() {
|
|
|
|
let change_request = FlattenStructTagContentEnumWrapper {
|
|
|
|
outer: 42,
|
2018-04-30 03:41:22 -05:00
|
|
|
data: FlattenStructTagContentEnumNewtype(FlattenStructTagContentEnum::InsertInteger {
|
|
|
|
index: 0,
|
|
|
|
value: 42,
|
|
|
|
}),
|
2018-03-16 16:58:16 -05:00
|
|
|
};
|
|
|
|
assert_de_tokens(
|
|
|
|
&change_request,
|
|
|
|
&[
|
|
|
|
Token::Map { len: None },
|
|
|
|
Token::Str("outer"),
|
|
|
|
Token::U32(42),
|
|
|
|
Token::Str("type"),
|
|
|
|
Token::Str("insert_integer"),
|
|
|
|
Token::Str("value"),
|
|
|
|
Token::Map { len: None },
|
|
|
|
Token::Str("index"),
|
|
|
|
Token::U32(0),
|
|
|
|
Token::Str("value"),
|
|
|
|
Token::U32(42),
|
|
|
|
Token::MapEnd,
|
|
|
|
Token::MapEnd,
|
|
|
|
],
|
|
|
|
);
|
|
|
|
assert_ser_tokens(
|
|
|
|
&change_request,
|
|
|
|
&[
|
|
|
|
Token::Map { len: None },
|
|
|
|
Token::Str("outer"),
|
|
|
|
Token::U32(42),
|
|
|
|
Token::Str("type"),
|
|
|
|
Token::Str("insert_integer"),
|
|
|
|
Token::Str("value"),
|
2018-04-30 03:41:22 -05:00
|
|
|
Token::Struct {
|
|
|
|
len: 2,
|
|
|
|
name: "insert_integer",
|
|
|
|
},
|
2018-03-16 16:58:16 -05:00
|
|
|
Token::Str("index"),
|
|
|
|
Token::U32(0),
|
|
|
|
Token::Str("value"),
|
|
|
|
Token::U32(42),
|
|
|
|
Token::StructEnd,
|
|
|
|
Token::MapEnd,
|
|
|
|
],
|
|
|
|
);
|
|
|
|
}
|
2018-03-18 07:10:54 -05:00
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_flatten_struct_tag_content_enum_newtype() {
|
|
|
|
let change_request = FlattenStructTagContentEnumWrapper {
|
|
|
|
outer: 42,
|
2018-04-30 03:41:22 -05:00
|
|
|
data: FlattenStructTagContentEnumNewtype(FlattenStructTagContentEnum::NewtypeVariant(
|
|
|
|
FlattenStructTagContentEnumNewtypeVariant { value: 23 },
|
|
|
|
)),
|
2018-03-18 07:10:54 -05:00
|
|
|
};
|
|
|
|
assert_de_tokens(
|
|
|
|
&change_request,
|
|
|
|
&[
|
|
|
|
Token::Map { len: None },
|
|
|
|
Token::Str("outer"),
|
|
|
|
Token::U32(42),
|
|
|
|
Token::Str("type"),
|
|
|
|
Token::Str("newtype_variant"),
|
|
|
|
Token::Str("value"),
|
|
|
|
Token::Map { len: None },
|
|
|
|
Token::Str("value"),
|
|
|
|
Token::U32(23),
|
|
|
|
Token::MapEnd,
|
|
|
|
Token::MapEnd,
|
|
|
|
],
|
|
|
|
);
|
|
|
|
assert_ser_tokens(
|
|
|
|
&change_request,
|
|
|
|
&[
|
|
|
|
Token::Map { len: None },
|
|
|
|
Token::Str("outer"),
|
|
|
|
Token::U32(42),
|
|
|
|
Token::Str("type"),
|
|
|
|
Token::Str("newtype_variant"),
|
|
|
|
Token::Str("value"),
|
2018-04-30 03:41:22 -05:00
|
|
|
Token::Struct {
|
|
|
|
len: 1,
|
|
|
|
name: "FlattenStructTagContentEnumNewtypeVariant",
|
|
|
|
},
|
2018-03-18 07:10:54 -05:00
|
|
|
Token::Str("value"),
|
|
|
|
Token::U32(23),
|
|
|
|
Token::StructEnd,
|
|
|
|
Token::MapEnd,
|
|
|
|
],
|
|
|
|
);
|
|
|
|
}
|
2018-03-18 12:22:06 -05:00
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_unknown_field_in_flatten() {
|
|
|
|
#[derive(Debug, PartialEq, Serialize, Deserialize)]
|
2018-03-18 12:30:46 -05:00
|
|
|
#[serde(deny_unknown_fields)]
|
2018-03-18 12:22:06 -05:00
|
|
|
struct Outer {
|
|
|
|
dummy: String,
|
|
|
|
#[serde(flatten)]
|
|
|
|
inner: Inner,
|
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Debug, PartialEq, Serialize, Deserialize)]
|
|
|
|
struct Inner {
|
|
|
|
foo: HashMap<String, u32>,
|
|
|
|
}
|
|
|
|
|
|
|
|
assert_de_tokens_error::<Outer>(
|
|
|
|
&[
|
|
|
|
Token::Struct {
|
|
|
|
name: "Outer",
|
|
|
|
len: 1,
|
|
|
|
},
|
|
|
|
Token::Str("dummy"),
|
|
|
|
Token::Str("23"),
|
|
|
|
Token::Str("foo"),
|
|
|
|
Token::Map { len: None },
|
|
|
|
Token::Str("a"),
|
|
|
|
Token::U32(1),
|
|
|
|
Token::Str("b"),
|
|
|
|
Token::U32(2),
|
|
|
|
Token::MapEnd,
|
|
|
|
Token::Str("bar"),
|
|
|
|
Token::U32(23),
|
|
|
|
Token::StructEnd,
|
|
|
|
],
|
|
|
|
"unknown field `bar`",
|
|
|
|
);
|
|
|
|
}
|
2018-03-18 17:01:13 -05:00
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_complex_flatten() {
|
|
|
|
#[derive(Debug, PartialEq, Serialize, Deserialize)]
|
|
|
|
struct Outer {
|
|
|
|
y: u32,
|
|
|
|
#[serde(flatten)]
|
|
|
|
first: First,
|
|
|
|
#[serde(flatten)]
|
|
|
|
second: Second,
|
2018-04-30 03:41:22 -05:00
|
|
|
z: u32,
|
2018-03-18 17:01:13 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Debug, PartialEq, Serialize, Deserialize)]
|
|
|
|
struct First {
|
|
|
|
a: u32,
|
|
|
|
b: bool,
|
|
|
|
c: Vec<String>,
|
|
|
|
d: String,
|
|
|
|
e: Option<u64>,
|
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Debug, PartialEq, Serialize, Deserialize)]
|
|
|
|
struct Second {
|
|
|
|
f: u32,
|
|
|
|
}
|
|
|
|
|
|
|
|
assert_de_tokens(
|
|
|
|
&Outer {
|
|
|
|
y: 0,
|
|
|
|
first: First {
|
|
|
|
a: 1,
|
|
|
|
b: true,
|
|
|
|
c: vec!["a".into(), "b".into()],
|
|
|
|
d: "c".into(),
|
|
|
|
e: Some(2),
|
|
|
|
},
|
2018-04-30 03:41:22 -05:00
|
|
|
second: Second { f: 3 },
|
|
|
|
z: 4,
|
2018-03-18 17:01:13 -05:00
|
|
|
},
|
|
|
|
&[
|
|
|
|
Token::Map { len: None },
|
|
|
|
Token::Str("y"),
|
|
|
|
Token::U32(0),
|
|
|
|
Token::Str("a"),
|
|
|
|
Token::U32(1),
|
|
|
|
Token::Str("b"),
|
|
|
|
Token::Bool(true),
|
|
|
|
Token::Str("c"),
|
|
|
|
Token::Seq { len: Some(2) },
|
|
|
|
Token::Str("a"),
|
|
|
|
Token::Str("b"),
|
|
|
|
Token::SeqEnd,
|
|
|
|
Token::Str("d"),
|
|
|
|
Token::Str("c"),
|
|
|
|
Token::Str("e"),
|
|
|
|
Token::U64(2),
|
|
|
|
Token::Str("f"),
|
|
|
|
Token::U32(3),
|
|
|
|
Token::Str("z"),
|
|
|
|
Token::U32(4),
|
|
|
|
Token::MapEnd,
|
|
|
|
],
|
|
|
|
);
|
|
|
|
|
|
|
|
assert_ser_tokens(
|
|
|
|
&Outer {
|
|
|
|
y: 0,
|
|
|
|
first: First {
|
|
|
|
a: 1,
|
|
|
|
b: true,
|
|
|
|
c: vec!["a".into(), "b".into()],
|
|
|
|
d: "c".into(),
|
|
|
|
e: Some(2),
|
|
|
|
},
|
2018-04-30 03:41:22 -05:00
|
|
|
second: Second { f: 3 },
|
|
|
|
z: 4,
|
2018-03-18 17:01:13 -05:00
|
|
|
},
|
|
|
|
&[
|
|
|
|
Token::Map { len: None },
|
|
|
|
Token::Str("y"),
|
|
|
|
Token::U32(0),
|
|
|
|
Token::Str("a"),
|
|
|
|
Token::U32(1),
|
|
|
|
Token::Str("b"),
|
|
|
|
Token::Bool(true),
|
|
|
|
Token::Str("c"),
|
|
|
|
Token::Seq { len: Some(2) },
|
|
|
|
Token::Str("a"),
|
|
|
|
Token::Str("b"),
|
|
|
|
Token::SeqEnd,
|
|
|
|
Token::Str("d"),
|
|
|
|
Token::Str("c"),
|
|
|
|
Token::Str("e"),
|
|
|
|
Token::Some,
|
|
|
|
Token::U64(2),
|
|
|
|
Token::Str("f"),
|
|
|
|
Token::U32(3),
|
|
|
|
Token::Str("z"),
|
|
|
|
Token::U32(4),
|
|
|
|
Token::MapEnd,
|
|
|
|
],
|
|
|
|
);
|
|
|
|
}
|
2018-03-18 17:46:28 -05:00
|
|
|
|
2018-06-01 14:00:35 -05:00
|
|
|
#[test]
|
|
|
|
fn test_flatten_map_twice() {
|
|
|
|
#[derive(Debug, PartialEq, Deserialize)]
|
|
|
|
struct Outer {
|
|
|
|
#[serde(flatten)]
|
|
|
|
first: BTreeMap<String, String>,
|
|
|
|
#[serde(flatten)]
|
|
|
|
between: Inner,
|
|
|
|
#[serde(flatten)]
|
|
|
|
second: BTreeMap<String, String>,
|
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Debug, PartialEq, Deserialize)]
|
|
|
|
struct Inner {
|
|
|
|
y: String,
|
|
|
|
}
|
|
|
|
|
|
|
|
assert_de_tokens(
|
|
|
|
&Outer {
|
|
|
|
first: {
|
|
|
|
let mut first = BTreeMap::new();
|
|
|
|
first.insert("x".to_owned(), "X".to_owned());
|
|
|
|
first.insert("y".to_owned(), "Y".to_owned());
|
|
|
|
first
|
|
|
|
},
|
|
|
|
between: Inner { y: "Y".to_owned() },
|
|
|
|
second: {
|
|
|
|
let mut second = BTreeMap::new();
|
|
|
|
second.insert("x".to_owned(), "X".to_owned());
|
|
|
|
second
|
|
|
|
},
|
|
|
|
},
|
|
|
|
&[
|
|
|
|
Token::Map { len: None },
|
|
|
|
Token::Str("x"),
|
|
|
|
Token::Str("X"),
|
|
|
|
Token::Str("y"),
|
|
|
|
Token::Str("Y"),
|
|
|
|
Token::MapEnd,
|
|
|
|
],
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2020-08-10 17:06:34 -05:00
|
|
|
#[test]
|
|
|
|
fn test_flatten_unit() {
|
|
|
|
#[derive(Debug, PartialEq, Serialize, Deserialize)]
|
|
|
|
struct Response<T> {
|
|
|
|
#[serde(flatten)]
|
|
|
|
data: T,
|
|
|
|
status: usize,
|
|
|
|
}
|
|
|
|
|
|
|
|
assert_tokens(
|
|
|
|
&Response {
|
|
|
|
data: (),
|
|
|
|
status: 0,
|
|
|
|
},
|
|
|
|
&[
|
|
|
|
Token::Map { len: None },
|
|
|
|
Token::Str("status"),
|
|
|
|
Token::U64(0),
|
|
|
|
Token::MapEnd,
|
|
|
|
],
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2018-03-18 17:46:28 -05:00
|
|
|
#[test]
|
|
|
|
fn test_flatten_unsupported_type() {
|
|
|
|
#[derive(Debug, PartialEq, Serialize, Deserialize)]
|
|
|
|
struct Outer {
|
|
|
|
outer: String,
|
|
|
|
#[serde(flatten)]
|
|
|
|
inner: String,
|
|
|
|
}
|
|
|
|
|
|
|
|
assert_ser_tokens_error(
|
|
|
|
&Outer {
|
|
|
|
outer: "foo".into(),
|
|
|
|
inner: "bar".into(),
|
|
|
|
},
|
|
|
|
&[
|
|
|
|
Token::Map { len: None },
|
|
|
|
Token::Str("outer"),
|
|
|
|
Token::Str("foo"),
|
|
|
|
],
|
|
|
|
"can only flatten structs and maps (got a string)",
|
|
|
|
);
|
|
|
|
assert_de_tokens_error::<Outer>(
|
|
|
|
&[
|
|
|
|
Token::Map { len: None },
|
|
|
|
Token::Str("outer"),
|
|
|
|
Token::Str("foo"),
|
|
|
|
Token::Str("a"),
|
|
|
|
Token::Str("b"),
|
2018-04-30 03:41:22 -05:00
|
|
|
Token::MapEnd,
|
2018-03-18 17:46:28 -05:00
|
|
|
],
|
|
|
|
"can only flatten structs and maps",
|
|
|
|
);
|
|
|
|
}
|
2018-03-18 18:57:58 -05:00
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_non_string_keys() {
|
|
|
|
#[derive(Debug, PartialEq, Serialize, Deserialize)]
|
|
|
|
struct TestStruct {
|
|
|
|
name: String,
|
|
|
|
age: u32,
|
|
|
|
#[serde(flatten)]
|
|
|
|
mapping: HashMap<u32, u32>,
|
|
|
|
}
|
|
|
|
|
|
|
|
let mut mapping = HashMap::new();
|
|
|
|
mapping.insert(0, 42);
|
|
|
|
assert_tokens(
|
2018-04-30 03:41:22 -05:00
|
|
|
&TestStruct {
|
|
|
|
name: "peter".into(),
|
|
|
|
age: 3,
|
|
|
|
mapping,
|
|
|
|
},
|
2018-03-18 18:57:58 -05:00
|
|
|
&[
|
|
|
|
Token::Map { len: None },
|
|
|
|
Token::Str("name"),
|
|
|
|
Token::Str("peter"),
|
|
|
|
Token::Str("age"),
|
|
|
|
Token::U32(3),
|
|
|
|
Token::U32(0),
|
|
|
|
Token::U32(42),
|
|
|
|
Token::MapEnd,
|
|
|
|
],
|
|
|
|
);
|
|
|
|
}
|
2018-03-20 09:19:36 -05:00
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_lifetime_propagation_for_flatten() {
|
|
|
|
#[derive(Deserialize, Serialize, Debug, PartialEq)]
|
|
|
|
struct A<T> {
|
|
|
|
#[serde(flatten)]
|
|
|
|
t: T,
|
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Deserialize, Serialize, Debug, PartialEq)]
|
|
|
|
struct B<'a> {
|
|
|
|
#[serde(flatten, borrow)]
|
|
|
|
t: HashMap<&'a str, u32>,
|
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Deserialize, Serialize, Debug, PartialEq)]
|
|
|
|
struct C<'a> {
|
|
|
|
#[serde(flatten, borrow)]
|
|
|
|
t: HashMap<&'a [u8], u32>,
|
|
|
|
}
|
|
|
|
|
|
|
|
let mut owned_map = HashMap::new();
|
|
|
|
owned_map.insert("x".to_string(), 42u32);
|
|
|
|
assert_tokens(
|
|
|
|
&A { t: owned_map },
|
|
|
|
&[
|
|
|
|
Token::Map { len: None },
|
|
|
|
Token::Str("x"),
|
|
|
|
Token::U32(42),
|
|
|
|
Token::MapEnd,
|
|
|
|
],
|
|
|
|
);
|
|
|
|
|
|
|
|
let mut borrowed_map = HashMap::new();
|
|
|
|
borrowed_map.insert("x", 42u32);
|
|
|
|
assert_ser_tokens(
|
2018-04-30 03:41:22 -05:00
|
|
|
&B {
|
|
|
|
t: borrowed_map.clone(),
|
|
|
|
},
|
2018-03-20 09:19:36 -05:00
|
|
|
&[
|
|
|
|
Token::Map { len: None },
|
|
|
|
Token::BorrowedStr("x"),
|
|
|
|
Token::U32(42),
|
|
|
|
Token::MapEnd,
|
|
|
|
],
|
|
|
|
);
|
|
|
|
|
|
|
|
assert_de_tokens(
|
|
|
|
&B { t: borrowed_map },
|
|
|
|
&[
|
|
|
|
Token::Map { len: None },
|
|
|
|
Token::BorrowedStr("x"),
|
|
|
|
Token::U32(42),
|
|
|
|
Token::MapEnd,
|
|
|
|
],
|
|
|
|
);
|
|
|
|
|
|
|
|
let mut borrowed_map = HashMap::new();
|
|
|
|
borrowed_map.insert(&b"x"[..], 42u32);
|
|
|
|
assert_ser_tokens(
|
2018-04-30 03:41:22 -05:00
|
|
|
&C {
|
|
|
|
t: borrowed_map.clone(),
|
|
|
|
},
|
2018-03-20 09:19:36 -05:00
|
|
|
&[
|
|
|
|
Token::Map { len: None },
|
|
|
|
Token::Seq { len: Some(1) },
|
|
|
|
Token::U8(120),
|
|
|
|
Token::SeqEnd,
|
|
|
|
Token::U32(42),
|
|
|
|
Token::MapEnd,
|
|
|
|
],
|
|
|
|
);
|
|
|
|
|
|
|
|
assert_de_tokens(
|
|
|
|
&C { t: borrowed_map },
|
|
|
|
&[
|
|
|
|
Token::Map { len: None },
|
|
|
|
Token::BorrowedBytes(b"x"),
|
|
|
|
Token::U32(42),
|
|
|
|
Token::MapEnd,
|
|
|
|
],
|
|
|
|
);
|
|
|
|
}
|
2018-03-20 17:05:05 -05:00
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_flatten_enum_newtype() {
|
|
|
|
#[derive(Serialize, Deserialize, PartialEq, Debug)]
|
|
|
|
struct S {
|
|
|
|
#[serde(flatten)]
|
|
|
|
flat: E,
|
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Serialize, Deserialize, PartialEq, Debug)]
|
|
|
|
enum E {
|
|
|
|
Q(HashMap<String, String>),
|
|
|
|
}
|
|
|
|
|
|
|
|
let e = E::Q({
|
|
|
|
let mut map = HashMap::new();
|
|
|
|
map.insert("k".to_owned(), "v".to_owned());
|
|
|
|
map
|
|
|
|
});
|
|
|
|
let s = S { flat: e };
|
|
|
|
|
|
|
|
assert_tokens(
|
|
|
|
&s,
|
|
|
|
&[
|
|
|
|
Token::Map { len: None },
|
|
|
|
Token::Str("Q"),
|
|
|
|
Token::Map { len: Some(1) },
|
|
|
|
Token::Str("k"),
|
|
|
|
Token::Str("v"),
|
|
|
|
Token::MapEnd,
|
|
|
|
Token::MapEnd,
|
|
|
|
],
|
|
|
|
);
|
|
|
|
}
|
2018-05-05 23:25:54 -05:00
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_flatten_internally_tagged() {
|
|
|
|
#[derive(Serialize, Deserialize, PartialEq, Debug)]
|
|
|
|
struct S {
|
|
|
|
#[serde(flatten)]
|
|
|
|
x: X,
|
|
|
|
#[serde(flatten)]
|
|
|
|
y: Y,
|
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Serialize, Deserialize, PartialEq, Debug)]
|
|
|
|
#[serde(tag = "typeX")]
|
|
|
|
enum X {
|
|
|
|
A { a: i32 },
|
|
|
|
B { b: i32 },
|
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Serialize, Deserialize, PartialEq, Debug)]
|
|
|
|
#[serde(tag = "typeY")]
|
|
|
|
enum Y {
|
|
|
|
C { c: i32 },
|
|
|
|
D { d: i32 },
|
|
|
|
}
|
|
|
|
|
|
|
|
let s = S {
|
|
|
|
x: X::B { b: 1 },
|
|
|
|
y: Y::D { d: 2 },
|
|
|
|
};
|
|
|
|
|
|
|
|
assert_tokens(
|
|
|
|
&s,
|
|
|
|
&[
|
|
|
|
Token::Map { len: None },
|
|
|
|
Token::Str("typeX"),
|
|
|
|
Token::Str("B"),
|
|
|
|
Token::Str("b"),
|
|
|
|
Token::I32(1),
|
|
|
|
Token::Str("typeY"),
|
|
|
|
Token::Str("D"),
|
|
|
|
Token::Str("d"),
|
|
|
|
Token::I32(2),
|
|
|
|
Token::MapEnd,
|
|
|
|
],
|
|
|
|
);
|
|
|
|
}
|
2018-05-06 23:23:20 -05:00
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_externally_tagged_enum_containing_flatten() {
|
|
|
|
#[derive(Serialize, Deserialize, PartialEq, Debug)]
|
|
|
|
enum Data {
|
|
|
|
A {
|
|
|
|
a: i32,
|
|
|
|
#[serde(flatten)]
|
|
|
|
flat: Flat,
|
2018-05-06 23:38:41 -05:00
|
|
|
},
|
2018-05-06 23:23:20 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Serialize, Deserialize, PartialEq, Debug)]
|
|
|
|
struct Flat {
|
|
|
|
b: i32,
|
|
|
|
}
|
|
|
|
|
|
|
|
let data = Data::A {
|
|
|
|
a: 0,
|
2018-05-06 23:38:41 -05:00
|
|
|
flat: Flat { b: 0 },
|
2018-05-06 23:23:20 -05:00
|
|
|
};
|
|
|
|
|
|
|
|
assert_tokens(
|
|
|
|
&data,
|
|
|
|
&[
|
2018-05-06 23:38:41 -05:00
|
|
|
Token::NewtypeVariant {
|
|
|
|
name: "Data",
|
|
|
|
variant: "A",
|
|
|
|
},
|
2018-05-06 23:23:20 -05:00
|
|
|
Token::Map { len: None },
|
|
|
|
Token::Str("a"),
|
|
|
|
Token::I32(0),
|
|
|
|
Token::Str("b"),
|
|
|
|
Token::I32(0),
|
|
|
|
Token::MapEnd,
|
|
|
|
],
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_internally_tagged_enum_containing_flatten() {
|
|
|
|
#[derive(Serialize, Deserialize, PartialEq, Debug)]
|
|
|
|
#[serde(tag = "t")]
|
|
|
|
enum Data {
|
|
|
|
A {
|
|
|
|
a: i32,
|
|
|
|
#[serde(flatten)]
|
|
|
|
flat: Flat,
|
2018-05-06 23:38:41 -05:00
|
|
|
},
|
2018-05-06 23:23:20 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Serialize, Deserialize, PartialEq, Debug)]
|
|
|
|
struct Flat {
|
|
|
|
b: i32,
|
|
|
|
}
|
|
|
|
|
|
|
|
let data = Data::A {
|
|
|
|
a: 0,
|
2018-05-06 23:38:41 -05:00
|
|
|
flat: Flat { b: 0 },
|
2018-05-06 23:23:20 -05:00
|
|
|
};
|
|
|
|
|
|
|
|
assert_tokens(
|
|
|
|
&data,
|
|
|
|
&[
|
|
|
|
Token::Map { len: None },
|
|
|
|
Token::Str("t"),
|
|
|
|
Token::Str("A"),
|
|
|
|
Token::Str("a"),
|
|
|
|
Token::I32(0),
|
|
|
|
Token::Str("b"),
|
|
|
|
Token::I32(0),
|
|
|
|
Token::MapEnd,
|
|
|
|
],
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2022-10-20 17:27:46 -05:00
|
|
|
#[test]
|
|
|
|
fn test_internally_tagged_enum_new_type_with_unit() {
|
|
|
|
#[derive(Serialize, Deserialize, PartialEq, Debug)]
|
|
|
|
#[serde(tag = "t")]
|
|
|
|
enum Data {
|
|
|
|
A(()),
|
|
|
|
}
|
|
|
|
|
|
|
|
assert_tokens(
|
|
|
|
&Data::A(()),
|
|
|
|
&[
|
|
|
|
Token::Map { len: Some(1) },
|
|
|
|
Token::Str("t"),
|
|
|
|
Token::Str("A"),
|
|
|
|
Token::MapEnd,
|
|
|
|
],
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2023-02-18 14:49:23 -06:00
|
|
|
#[test]
|
|
|
|
fn test_adjacently_tagged_enum_bytes() {
|
|
|
|
#[derive(Serialize, Deserialize, PartialEq, Debug)]
|
|
|
|
#[serde(tag = "t", content = "c")]
|
|
|
|
enum Data {
|
|
|
|
A { a: i32 },
|
|
|
|
}
|
|
|
|
|
|
|
|
let data = Data::A { a: 0 };
|
|
|
|
|
|
|
|
assert_tokens(
|
|
|
|
&data,
|
|
|
|
&[
|
|
|
|
Token::Struct {
|
|
|
|
name: "Data",
|
|
|
|
len: 2,
|
|
|
|
},
|
|
|
|
Token::Str("t"),
|
|
|
|
Token::Str("A"),
|
|
|
|
Token::Str("c"),
|
2023-05-04 20:42:02 -05:00
|
|
|
Token::Struct { name: "A", len: 1 },
|
2023-02-18 14:49:23 -06:00
|
|
|
Token::Str("a"),
|
|
|
|
Token::I32(0),
|
|
|
|
Token::StructEnd,
|
|
|
|
Token::StructEnd,
|
|
|
|
],
|
|
|
|
);
|
|
|
|
|
|
|
|
assert_de_tokens(
|
|
|
|
&data,
|
|
|
|
&[
|
|
|
|
Token::Struct {
|
|
|
|
name: "Data",
|
|
|
|
len: 2,
|
|
|
|
},
|
|
|
|
Token::Bytes(b"t"),
|
|
|
|
Token::Str("A"),
|
|
|
|
Token::Bytes(b"c"),
|
2023-05-04 20:42:02 -05:00
|
|
|
Token::Struct { name: "A", len: 1 },
|
2023-02-18 14:49:23 -06:00
|
|
|
Token::Str("a"),
|
|
|
|
Token::I32(0),
|
|
|
|
Token::StructEnd,
|
|
|
|
Token::StructEnd,
|
|
|
|
],
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2018-05-06 23:23:20 -05:00
|
|
|
#[test]
|
|
|
|
fn test_adjacently_tagged_enum_containing_flatten() {
|
|
|
|
#[derive(Serialize, Deserialize, PartialEq, Debug)]
|
|
|
|
#[serde(tag = "t", content = "c")]
|
|
|
|
enum Data {
|
|
|
|
A {
|
|
|
|
a: i32,
|
|
|
|
#[serde(flatten)]
|
|
|
|
flat: Flat,
|
2018-05-06 23:38:41 -05:00
|
|
|
},
|
2018-05-06 23:23:20 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Serialize, Deserialize, PartialEq, Debug)]
|
|
|
|
struct Flat {
|
|
|
|
b: i32,
|
|
|
|
}
|
|
|
|
|
|
|
|
let data = Data::A {
|
|
|
|
a: 0,
|
2018-05-06 23:38:41 -05:00
|
|
|
flat: Flat { b: 0 },
|
2018-05-06 23:23:20 -05:00
|
|
|
};
|
|
|
|
|
|
|
|
assert_tokens(
|
|
|
|
&data,
|
|
|
|
&[
|
2018-05-06 23:38:41 -05:00
|
|
|
Token::Struct {
|
|
|
|
name: "Data",
|
|
|
|
len: 2,
|
|
|
|
},
|
2018-05-06 23:23:20 -05:00
|
|
|
Token::Str("t"),
|
|
|
|
Token::Str("A"),
|
|
|
|
Token::Str("c"),
|
|
|
|
Token::Map { len: None },
|
|
|
|
Token::Str("a"),
|
|
|
|
Token::I32(0),
|
|
|
|
Token::Str("b"),
|
|
|
|
Token::I32(0),
|
|
|
|
Token::MapEnd,
|
|
|
|
Token::StructEnd,
|
|
|
|
],
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_untagged_enum_containing_flatten() {
|
|
|
|
#[derive(Serialize, Deserialize, PartialEq, Debug)]
|
|
|
|
#[serde(untagged)]
|
|
|
|
enum Data {
|
|
|
|
A {
|
|
|
|
a: i32,
|
|
|
|
#[serde(flatten)]
|
|
|
|
flat: Flat,
|
2018-05-06 23:38:41 -05:00
|
|
|
},
|
2018-05-06 23:23:20 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Serialize, Deserialize, PartialEq, Debug)]
|
|
|
|
struct Flat {
|
|
|
|
b: i32,
|
|
|
|
}
|
|
|
|
|
|
|
|
let data = Data::A {
|
|
|
|
a: 0,
|
2018-05-06 23:38:41 -05:00
|
|
|
flat: Flat { b: 0 },
|
2018-05-06 23:23:20 -05:00
|
|
|
};
|
|
|
|
|
|
|
|
assert_tokens(
|
|
|
|
&data,
|
|
|
|
&[
|
|
|
|
Token::Map { len: None },
|
|
|
|
Token::Str("a"),
|
|
|
|
Token::I32(0),
|
|
|
|
Token::Str("b"),
|
|
|
|
Token::I32(0),
|
|
|
|
Token::MapEnd,
|
|
|
|
],
|
|
|
|
);
|
|
|
|
}
|
2018-05-10 10:33:47 -05:00
|
|
|
|
2023-06-07 22:58:59 -05:00
|
|
|
#[test]
|
|
|
|
fn test_partially_untagged_enum() {
|
|
|
|
#[derive(Serialize, Deserialize, PartialEq, Debug)]
|
|
|
|
enum Exp {
|
|
|
|
Lambda(u32, Box<Exp>),
|
|
|
|
#[serde(untagged)]
|
|
|
|
App(Box<Exp>, Box<Exp>),
|
|
|
|
#[serde(untagged)]
|
|
|
|
Var(u32),
|
|
|
|
}
|
|
|
|
use Exp::*;
|
|
|
|
|
|
|
|
let data = Lambda(0, Box::new(App(Box::new(Var(0)), Box::new(Var(0)))));
|
|
|
|
assert_tokens(
|
|
|
|
&data,
|
|
|
|
&[
|
|
|
|
Token::TupleVariant {
|
|
|
|
name: "Exp",
|
|
|
|
variant: "Lambda",
|
|
|
|
len: 2,
|
|
|
|
},
|
|
|
|
Token::U32(0),
|
|
|
|
Token::Tuple { len: 2 },
|
|
|
|
Token::U32(0),
|
|
|
|
Token::U32(0),
|
|
|
|
Token::TupleEnd,
|
|
|
|
Token::TupleVariantEnd,
|
|
|
|
],
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_partially_untagged_enum_generic() {
|
|
|
|
trait Trait<T> {
|
|
|
|
type Assoc;
|
|
|
|
type Assoc2;
|
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Serialize, Deserialize, PartialEq, Debug)]
|
2023-06-07 23:18:30 -05:00
|
|
|
enum E<A, B, C>
|
|
|
|
where
|
|
|
|
A: Trait<C, Assoc2 = B>,
|
|
|
|
{
|
2023-06-07 22:58:59 -05:00
|
|
|
A(A::Assoc),
|
|
|
|
#[serde(untagged)]
|
|
|
|
B(A::Assoc2),
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<T> Trait<T> for () {
|
|
|
|
type Assoc = T;
|
|
|
|
type Assoc2 = bool;
|
|
|
|
}
|
|
|
|
|
|
|
|
type MyE = E<(), bool, u32>;
|
|
|
|
use E::*;
|
|
|
|
|
|
|
|
assert_tokens::<MyE>(&B(true), &[Token::Bool(true)]);
|
|
|
|
|
|
|
|
assert_tokens::<MyE>(
|
|
|
|
&A(5),
|
|
|
|
&[
|
|
|
|
Token::NewtypeVariant {
|
|
|
|
name: "E",
|
|
|
|
variant: "A",
|
|
|
|
},
|
|
|
|
Token::U32(5),
|
|
|
|
],
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_partially_untagged_enum_desugared() {
|
|
|
|
#[derive(Serialize, Deserialize, PartialEq, Debug)]
|
|
|
|
enum Test {
|
|
|
|
A(u32, u32),
|
|
|
|
B(u32),
|
|
|
|
#[serde(untagged)]
|
|
|
|
C(u32),
|
|
|
|
#[serde(untagged)]
|
|
|
|
D(u32, u32),
|
|
|
|
}
|
|
|
|
use Test::*;
|
|
|
|
|
|
|
|
mod desugared {
|
|
|
|
use super::*;
|
|
|
|
#[derive(Serialize, Deserialize, PartialEq, Debug)]
|
|
|
|
pub(super) enum Test {
|
|
|
|
A(u32, u32),
|
|
|
|
B(u32),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
use desugared::Test as TestTagged;
|
|
|
|
|
|
|
|
#[derive(Serialize, Deserialize, PartialEq, Debug)]
|
|
|
|
#[serde(untagged)]
|
|
|
|
enum TestUntagged {
|
|
|
|
Tagged(TestTagged),
|
|
|
|
C(u32),
|
|
|
|
D(u32, u32),
|
|
|
|
}
|
|
|
|
|
|
|
|
impl From<Test> for TestUntagged {
|
|
|
|
fn from(test: Test) -> Self {
|
|
|
|
match test {
|
|
|
|
A(x, y) => TestUntagged::Tagged(TestTagged::A(x, y)),
|
|
|
|
B(x) => TestUntagged::Tagged(TestTagged::B(x)),
|
|
|
|
C(x) => TestUntagged::C(x),
|
|
|
|
D(x, y) => TestUntagged::D(x, y),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn assert_tokens_desugared(value: Test, tokens: &[Token]) {
|
|
|
|
assert_tokens(&value, tokens);
|
|
|
|
let desugared: TestUntagged = value.into();
|
|
|
|
assert_tokens(&desugared, tokens);
|
|
|
|
}
|
|
|
|
|
|
|
|
assert_tokens_desugared(
|
|
|
|
A(0, 1),
|
|
|
|
&[
|
|
|
|
Token::TupleVariant {
|
|
|
|
name: "Test",
|
|
|
|
variant: "A",
|
|
|
|
len: 2,
|
|
|
|
},
|
|
|
|
Token::U32(0),
|
|
|
|
Token::U32(1),
|
|
|
|
Token::TupleVariantEnd,
|
|
|
|
],
|
|
|
|
);
|
|
|
|
|
|
|
|
assert_tokens_desugared(
|
|
|
|
B(1),
|
|
|
|
&[
|
|
|
|
Token::NewtypeVariant {
|
|
|
|
name: "Test",
|
|
|
|
variant: "B",
|
|
|
|
},
|
|
|
|
Token::U32(1),
|
|
|
|
],
|
|
|
|
);
|
|
|
|
|
|
|
|
assert_tokens_desugared(C(2), &[Token::U32(2)]);
|
|
|
|
|
|
|
|
assert_tokens_desugared(
|
|
|
|
D(3, 5),
|
|
|
|
&[
|
|
|
|
Token::Tuple { len: 2 },
|
|
|
|
Token::U32(3),
|
|
|
|
Token::U32(5),
|
|
|
|
Token::TupleEnd,
|
|
|
|
],
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2018-05-10 10:33:47 -05:00
|
|
|
#[test]
|
|
|
|
fn test_flatten_untagged_enum() {
|
|
|
|
#[derive(Serialize, Deserialize, PartialEq, Debug)]
|
|
|
|
struct Outer {
|
|
|
|
#[serde(flatten)]
|
|
|
|
inner: Inner,
|
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Serialize, Deserialize, PartialEq, Debug)]
|
|
|
|
#[serde(untagged)]
|
|
|
|
enum Inner {
|
2018-05-19 19:33:30 -05:00
|
|
|
Variant { a: i32 },
|
2018-05-10 10:33:47 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
let data = Outer {
|
2018-05-19 19:33:30 -05:00
|
|
|
inner: Inner::Variant { a: 0 },
|
2018-05-10 10:33:47 -05:00
|
|
|
};
|
|
|
|
|
|
|
|
assert_tokens(
|
|
|
|
&data,
|
|
|
|
&[
|
|
|
|
Token::Map { len: None },
|
|
|
|
Token::Str("a"),
|
|
|
|
Token::I32(0),
|
|
|
|
Token::MapEnd,
|
|
|
|
],
|
|
|
|
);
|
|
|
|
}
|
2018-05-12 00:14:16 -05:00
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_flatten_option() {
|
|
|
|
#[derive(Serialize, Deserialize, PartialEq, Debug)]
|
|
|
|
struct Outer {
|
|
|
|
#[serde(flatten)]
|
|
|
|
inner1: Option<Inner1>,
|
|
|
|
#[serde(flatten)]
|
|
|
|
inner2: Option<Inner2>,
|
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Serialize, Deserialize, PartialEq, Debug)]
|
|
|
|
struct Inner1 {
|
|
|
|
inner1: i32,
|
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Serialize, Deserialize, PartialEq, Debug)]
|
|
|
|
struct Inner2 {
|
|
|
|
inner2: i32,
|
|
|
|
}
|
|
|
|
|
|
|
|
assert_tokens(
|
|
|
|
&Outer {
|
2018-05-19 19:33:30 -05:00
|
|
|
inner1: Some(Inner1 { inner1: 1 }),
|
|
|
|
inner2: Some(Inner2 { inner2: 2 }),
|
2018-05-12 00:14:16 -05:00
|
|
|
},
|
|
|
|
&[
|
|
|
|
Token::Map { len: None },
|
|
|
|
Token::Str("inner1"),
|
|
|
|
Token::I32(1),
|
|
|
|
Token::Str("inner2"),
|
|
|
|
Token::I32(2),
|
|
|
|
Token::MapEnd,
|
|
|
|
],
|
|
|
|
);
|
|
|
|
|
|
|
|
assert_tokens(
|
|
|
|
&Outer {
|
2018-05-19 19:33:30 -05:00
|
|
|
inner1: Some(Inner1 { inner1: 1 }),
|
2018-05-12 00:14:16 -05:00
|
|
|
inner2: None,
|
|
|
|
},
|
|
|
|
&[
|
|
|
|
Token::Map { len: None },
|
|
|
|
Token::Str("inner1"),
|
|
|
|
Token::I32(1),
|
|
|
|
Token::MapEnd,
|
|
|
|
],
|
|
|
|
);
|
|
|
|
|
|
|
|
assert_tokens(
|
|
|
|
&Outer {
|
|
|
|
inner1: None,
|
2018-05-19 19:33:30 -05:00
|
|
|
inner2: Some(Inner2 { inner2: 2 }),
|
2018-05-12 00:14:16 -05:00
|
|
|
},
|
|
|
|
&[
|
|
|
|
Token::Map { len: None },
|
|
|
|
Token::Str("inner2"),
|
|
|
|
Token::I32(2),
|
|
|
|
Token::MapEnd,
|
|
|
|
],
|
|
|
|
);
|
|
|
|
|
|
|
|
assert_tokens(
|
|
|
|
&Outer {
|
|
|
|
inner1: None,
|
|
|
|
inner2: None,
|
|
|
|
},
|
2018-05-19 19:33:30 -05:00
|
|
|
&[Token::Map { len: None }, Token::MapEnd],
|
2018-05-12 00:14:16 -05:00
|
|
|
);
|
|
|
|
}
|
2018-05-20 15:53:29 -05:00
|
|
|
|
2023-04-29 15:18:42 -05:00
|
|
|
#[test]
|
|
|
|
fn test_flatten_ignored_any() {
|
|
|
|
#[derive(Deserialize, PartialEq, Debug)]
|
|
|
|
struct Outer {
|
|
|
|
#[serde(flatten)]
|
|
|
|
inner: IgnoredAny,
|
|
|
|
}
|
|
|
|
|
|
|
|
assert_de_tokens(
|
|
|
|
&Outer { inner: IgnoredAny },
|
|
|
|
&[Token::Map { len: None }, Token::MapEnd],
|
|
|
|
);
|
|
|
|
|
|
|
|
assert_de_tokens(
|
|
|
|
&Outer { inner: IgnoredAny },
|
|
|
|
&[
|
|
|
|
Token::Struct {
|
|
|
|
name: "DoNotMatter",
|
|
|
|
len: 0,
|
|
|
|
},
|
|
|
|
Token::StructEnd,
|
|
|
|
],
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2018-05-20 15:53:29 -05:00
|
|
|
#[test]
|
|
|
|
fn test_transparent_struct() {
|
|
|
|
#[derive(Serialize, Deserialize, PartialEq, Debug)]
|
|
|
|
#[serde(transparent)]
|
|
|
|
struct Transparent {
|
|
|
|
#[serde(skip)]
|
|
|
|
a: bool,
|
|
|
|
b: u32,
|
|
|
|
#[serde(skip)]
|
|
|
|
c: bool,
|
|
|
|
d: PhantomData<()>,
|
|
|
|
}
|
|
|
|
|
|
|
|
assert_tokens(
|
|
|
|
&Transparent {
|
|
|
|
a: false,
|
|
|
|
b: 1,
|
|
|
|
c: false,
|
|
|
|
d: PhantomData,
|
|
|
|
},
|
|
|
|
&[Token::U32(1)],
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_transparent_tuple_struct() {
|
|
|
|
#[derive(Serialize, Deserialize, PartialEq, Debug)]
|
|
|
|
#[serde(transparent)]
|
|
|
|
struct Transparent(
|
|
|
|
#[serde(skip)] bool,
|
|
|
|
u32,
|
|
|
|
#[serde(skip)] bool,
|
|
|
|
PhantomData<()>,
|
|
|
|
);
|
|
|
|
|
|
|
|
assert_tokens(&Transparent(false, 1, false, PhantomData), &[Token::U32(1)]);
|
|
|
|
}
|
2018-09-06 16:29:49 -05:00
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_internally_tagged_unit_enum_with_unknown_fields() {
|
|
|
|
#[derive(Deserialize, PartialEq, Debug)]
|
|
|
|
#[serde(tag = "t")]
|
|
|
|
enum Data {
|
|
|
|
A,
|
|
|
|
}
|
|
|
|
|
|
|
|
let data = Data::A;
|
|
|
|
|
|
|
|
assert_de_tokens(
|
|
|
|
&data,
|
|
|
|
&[
|
|
|
|
Token::Map { len: None },
|
|
|
|
Token::Str("t"),
|
|
|
|
Token::Str("A"),
|
|
|
|
Token::Str("b"),
|
|
|
|
Token::I32(0),
|
|
|
|
Token::MapEnd,
|
|
|
|
],
|
|
|
|
);
|
|
|
|
}
|
2018-09-06 16:55:10 -05:00
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_flattened_internally_tagged_unit_enum_with_unknown_fields() {
|
|
|
|
#[derive(Deserialize, PartialEq, Debug)]
|
|
|
|
struct S {
|
|
|
|
#[serde(flatten)]
|
|
|
|
x: X,
|
|
|
|
#[serde(flatten)]
|
|
|
|
y: Y,
|
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Deserialize, PartialEq, Debug)]
|
|
|
|
#[serde(tag = "typeX")]
|
|
|
|
enum X {
|
|
|
|
A,
|
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Deserialize, PartialEq, Debug)]
|
|
|
|
#[serde(tag = "typeY")]
|
|
|
|
enum Y {
|
|
|
|
B { c: u32 },
|
|
|
|
}
|
|
|
|
|
|
|
|
let s = S {
|
|
|
|
x: X::A,
|
|
|
|
y: Y::B { c: 0 },
|
|
|
|
};
|
|
|
|
|
|
|
|
assert_de_tokens(
|
|
|
|
&s,
|
|
|
|
&[
|
|
|
|
Token::Map { len: None },
|
|
|
|
Token::Str("typeX"),
|
|
|
|
Token::Str("A"),
|
|
|
|
Token::Str("typeY"),
|
|
|
|
Token::Str("B"),
|
|
|
|
Token::Str("c"),
|
|
|
|
Token::I32(0),
|
|
|
|
Token::MapEnd,
|
|
|
|
],
|
|
|
|
);
|
|
|
|
}
|
2018-09-08 18:53:03 -05:00
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_flatten_any_after_flatten_struct() {
|
|
|
|
#[derive(PartialEq, Debug)]
|
|
|
|
struct Any;
|
|
|
|
|
|
|
|
impl<'de> Deserialize<'de> for Any {
|
|
|
|
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
|
|
|
where
|
|
|
|
D: Deserializer<'de>,
|
|
|
|
{
|
|
|
|
struct AnyVisitor;
|
|
|
|
|
|
|
|
impl<'de> Visitor<'de> for AnyVisitor {
|
|
|
|
type Value = Any;
|
|
|
|
|
|
|
|
fn expecting(&self, _formatter: &mut fmt::Formatter) -> fmt::Result {
|
|
|
|
unimplemented!()
|
|
|
|
}
|
|
|
|
|
|
|
|
fn visit_map<M>(self, mut map: M) -> Result<Self::Value, M::Error>
|
|
|
|
where
|
|
|
|
M: MapAccess<'de>,
|
|
|
|
{
|
|
|
|
while let Some((Any, Any)) = map.next_entry()? {}
|
|
|
|
Ok(Any)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
deserializer.deserialize_any(AnyVisitor)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Deserialize, PartialEq, Debug)]
|
|
|
|
struct Outer {
|
|
|
|
#[serde(flatten)]
|
|
|
|
inner: Inner,
|
|
|
|
#[serde(flatten)]
|
|
|
|
extra: Any,
|
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Deserialize, PartialEq, Debug)]
|
|
|
|
struct Inner {
|
|
|
|
inner: i32,
|
|
|
|
}
|
|
|
|
|
|
|
|
let s = Outer {
|
2018-09-12 01:00:08 -05:00
|
|
|
inner: Inner { inner: 0 },
|
2018-09-08 18:53:03 -05:00
|
|
|
extra: Any,
|
|
|
|
};
|
|
|
|
|
|
|
|
assert_de_tokens(
|
|
|
|
&s,
|
|
|
|
&[
|
|
|
|
Token::Map { len: None },
|
|
|
|
Token::Str("inner"),
|
|
|
|
Token::I32(0),
|
|
|
|
Token::MapEnd,
|
|
|
|
],
|
|
|
|
);
|
|
|
|
}
|
2020-10-22 14:54:13 -05:00
|
|
|
|
2023-03-06 18:09:01 -06:00
|
|
|
#[test]
|
|
|
|
fn test_alias_in_flatten_context() {
|
|
|
|
#[derive(Debug, PartialEq, Deserialize)]
|
|
|
|
struct Outer {
|
|
|
|
#[serde(flatten)]
|
|
|
|
a: AliasStruct,
|
|
|
|
b: i32,
|
|
|
|
}
|
|
|
|
|
|
|
|
assert_de_tokens(
|
|
|
|
&Outer {
|
|
|
|
a: AliasStruct {
|
|
|
|
a1: 1,
|
|
|
|
a2: 2,
|
|
|
|
a4: 4,
|
|
|
|
},
|
|
|
|
b: 7,
|
|
|
|
},
|
|
|
|
&[
|
|
|
|
Token::Struct {
|
|
|
|
name: "Outer",
|
|
|
|
len: 4,
|
|
|
|
},
|
|
|
|
Token::Str("a1"),
|
|
|
|
Token::I32(1),
|
|
|
|
Token::Str("a2"),
|
|
|
|
Token::I32(2),
|
|
|
|
Token::Str("a5"),
|
|
|
|
Token::I32(4),
|
|
|
|
Token::Str("b"),
|
|
|
|
Token::I32(7),
|
|
|
|
Token::StructEnd,
|
|
|
|
],
|
|
|
|
);
|
|
|
|
|
|
|
|
assert_de_tokens(
|
|
|
|
&Outer {
|
|
|
|
a: AliasStruct {
|
|
|
|
a1: 1,
|
|
|
|
a2: 2,
|
|
|
|
a4: 4,
|
|
|
|
},
|
|
|
|
b: 7,
|
|
|
|
},
|
|
|
|
&[
|
|
|
|
Token::Struct {
|
|
|
|
name: "Outer",
|
|
|
|
len: 4,
|
|
|
|
},
|
|
|
|
Token::Str("a1"),
|
|
|
|
Token::I32(1),
|
|
|
|
Token::Str("a2"),
|
|
|
|
Token::I32(2),
|
|
|
|
Token::Str("a6"),
|
|
|
|
Token::I32(4),
|
|
|
|
Token::Str("b"),
|
|
|
|
Token::I32(7),
|
|
|
|
Token::StructEnd,
|
|
|
|
],
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2020-10-22 14:54:13 -05:00
|
|
|
#[test]
|
|
|
|
fn test_expecting_message() {
|
|
|
|
#[derive(Deserialize, PartialEq, Debug)]
|
|
|
|
#[serde(expecting = "something strange...")]
|
|
|
|
struct Unit;
|
|
|
|
|
|
|
|
#[derive(Deserialize)]
|
|
|
|
#[serde(expecting = "something strange...")]
|
|
|
|
struct Newtype(bool);
|
|
|
|
|
|
|
|
#[derive(Deserialize)]
|
|
|
|
#[serde(expecting = "something strange...")]
|
|
|
|
struct Tuple(u32, bool);
|
|
|
|
|
|
|
|
#[derive(Deserialize)]
|
|
|
|
#[serde(expecting = "something strange...")]
|
|
|
|
struct Struct {
|
|
|
|
question: String,
|
|
|
|
answer: u32,
|
|
|
|
}
|
|
|
|
|
|
|
|
assert_de_tokens_error::<Unit>(
|
|
|
|
&[Token::Str("Unit")],
|
2021-01-23 15:39:12 -06:00
|
|
|
r#"invalid type: string "Unit", expected something strange..."#,
|
2020-10-22 14:54:13 -05:00
|
|
|
);
|
|
|
|
|
|
|
|
assert_de_tokens_error::<Newtype>(
|
|
|
|
&[Token::Str("Newtype")],
|
2021-01-23 15:39:12 -06:00
|
|
|
r#"invalid type: string "Newtype", expected something strange..."#,
|
2020-10-22 14:54:13 -05:00
|
|
|
);
|
|
|
|
|
|
|
|
assert_de_tokens_error::<Tuple>(
|
|
|
|
&[Token::Str("Tuple")],
|
2021-01-23 15:39:12 -06:00
|
|
|
r#"invalid type: string "Tuple", expected something strange..."#,
|
2020-10-22 14:54:13 -05:00
|
|
|
);
|
|
|
|
|
|
|
|
assert_de_tokens_error::<Struct>(
|
|
|
|
&[Token::Str("Struct")],
|
2021-01-23 15:39:12 -06:00
|
|
|
r#"invalid type: string "Struct", expected something strange..."#,
|
2020-10-22 14:54:13 -05:00
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_expecting_message_externally_tagged_enum() {
|
|
|
|
#[derive(Deserialize)]
|
|
|
|
#[serde(expecting = "something strange...")]
|
|
|
|
enum Enum {
|
|
|
|
ExternallyTagged,
|
|
|
|
}
|
|
|
|
|
|
|
|
assert_de_tokens_error::<Enum>(
|
2021-01-23 15:39:12 -06:00
|
|
|
&[Token::Str("ExternallyTagged")],
|
|
|
|
r#"invalid type: string "ExternallyTagged", expected something strange..."#,
|
2020-10-22 14:54:13 -05:00
|
|
|
);
|
|
|
|
|
|
|
|
// Check that #[serde(expecting = "...")] doesn't affect variant identifier error message
|
|
|
|
assert_de_tokens_error::<Enum>(
|
2021-01-23 15:39:12 -06:00
|
|
|
&[Token::Enum { name: "Enum" }, Token::Unit],
|
|
|
|
r#"invalid type: unit value, expected variant identifier"#,
|
2020-10-22 14:54:13 -05:00
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_expecting_message_internally_tagged_enum() {
|
|
|
|
#[derive(Deserialize)]
|
|
|
|
#[serde(tag = "tag")]
|
|
|
|
#[serde(expecting = "something strange...")]
|
|
|
|
enum Enum {
|
|
|
|
InternallyTagged,
|
|
|
|
}
|
|
|
|
|
|
|
|
assert_de_tokens_error::<Enum>(
|
2021-01-23 15:39:12 -06:00
|
|
|
&[Token::Str("InternallyTagged")],
|
|
|
|
r#"invalid type: string "InternallyTagged", expected something strange..."#,
|
2020-10-22 14:54:13 -05:00
|
|
|
);
|
|
|
|
|
|
|
|
// Check that #[serde(expecting = "...")] doesn't affect variant identifier error message
|
|
|
|
assert_de_tokens_error::<Enum>(
|
2021-01-23 15:39:12 -06:00
|
|
|
&[Token::Map { len: None }, Token::Str("tag"), Token::Unit],
|
|
|
|
r#"invalid type: unit value, expected variant identifier"#,
|
2020-10-22 14:54:13 -05:00
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_expecting_message_adjacently_tagged_enum() {
|
|
|
|
#[derive(Deserialize)]
|
|
|
|
#[serde(tag = "tag", content = "content")]
|
|
|
|
#[serde(expecting = "something strange...")]
|
|
|
|
enum Enum {
|
|
|
|
AdjacentlyTagged,
|
|
|
|
}
|
|
|
|
|
|
|
|
assert_de_tokens_error::<Enum>(
|
2021-01-23 15:39:12 -06:00
|
|
|
&[Token::Str("AdjacentlyTagged")],
|
|
|
|
r#"invalid type: string "AdjacentlyTagged", expected something strange..."#,
|
2020-10-22 14:54:13 -05:00
|
|
|
);
|
|
|
|
|
|
|
|
assert_de_tokens_error::<Enum>(
|
2021-01-23 15:39:12 -06:00
|
|
|
&[Token::Map { len: None }, Token::Unit],
|
|
|
|
r#"invalid type: unit value, expected "tag", "content", or other ignored fields"#,
|
2020-10-22 14:54:13 -05:00
|
|
|
);
|
|
|
|
|
|
|
|
// Check that #[serde(expecting = "...")] doesn't affect variant identifier error message
|
|
|
|
assert_de_tokens_error::<Enum>(
|
2021-01-23 15:39:12 -06:00
|
|
|
&[Token::Map { len: None }, Token::Str("tag"), Token::Unit],
|
|
|
|
r#"invalid type: unit value, expected variant identifier"#,
|
2020-10-22 14:54:13 -05:00
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_expecting_message_untagged_tagged_enum() {
|
|
|
|
#[derive(Deserialize)]
|
|
|
|
#[serde(untagged)]
|
|
|
|
#[serde(expecting = "something strange...")]
|
|
|
|
enum Enum {
|
|
|
|
Untagged,
|
|
|
|
}
|
|
|
|
|
2021-01-23 15:39:12 -06:00
|
|
|
assert_de_tokens_error::<Enum>(&[Token::Str("Untagged")], r#"something strange..."#);
|
2020-10-22 14:54:13 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_expecting_message_identifier_enum() {
|
|
|
|
#[derive(Deserialize)]
|
|
|
|
#[serde(field_identifier)]
|
|
|
|
#[serde(expecting = "something strange...")]
|
|
|
|
enum FieldEnum {
|
|
|
|
Field,
|
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Deserialize)]
|
|
|
|
#[serde(variant_identifier)]
|
|
|
|
#[serde(expecting = "something strange...")]
|
|
|
|
enum VariantEnum {
|
|
|
|
Variant,
|
|
|
|
}
|
|
|
|
|
|
|
|
assert_de_tokens_error::<FieldEnum>(
|
2021-01-23 15:39:12 -06:00
|
|
|
&[Token::Unit],
|
|
|
|
r#"invalid type: unit value, expected something strange..."#,
|
2020-10-22 14:54:13 -05:00
|
|
|
);
|
|
|
|
|
|
|
|
assert_de_tokens_error::<FieldEnum>(
|
|
|
|
&[
|
|
|
|
Token::Enum { name: "FieldEnum" },
|
|
|
|
Token::Str("Unknown"),
|
|
|
|
Token::None,
|
|
|
|
],
|
2021-01-23 15:39:12 -06:00
|
|
|
r#"invalid type: map, expected something strange..."#,
|
2020-10-22 14:54:13 -05:00
|
|
|
);
|
|
|
|
|
|
|
|
assert_de_tokens_error::<VariantEnum>(
|
2021-01-23 15:39:12 -06:00
|
|
|
&[Token::Unit],
|
|
|
|
r#"invalid type: unit value, expected something strange..."#,
|
2020-10-22 14:54:13 -05:00
|
|
|
);
|
|
|
|
|
|
|
|
assert_de_tokens_error::<VariantEnum>(
|
|
|
|
&[
|
2021-01-23 15:39:12 -06:00
|
|
|
Token::Enum {
|
|
|
|
name: "VariantEnum",
|
|
|
|
},
|
2020-10-22 14:54:13 -05:00
|
|
|
Token::Str("Unknown"),
|
|
|
|
Token::None,
|
|
|
|
],
|
2021-01-23 15:39:12 -06:00
|
|
|
r#"invalid type: map, expected something strange..."#,
|
2020-10-22 14:54:13 -05:00
|
|
|
);
|
|
|
|
}
|