1 use ron::{de::from_str, ser::to_string};
2 use serde::{Deserialize, Serialize};
3 use std::{cmp::PartialEq, fmt::Debug};
4 
5 #[derive(Debug, PartialEq, Eq, Serialize, Deserialize)]
6 enum Inner {
7     Foo,
8     Bar,
9 }
10 
11 #[derive(Debug, PartialEq, Eq, Serialize, Deserialize)]
12 enum EnumStructExternally {
13     VariantA { foo: u32, bar: u32, different: u32 },
14     VariantB { foo: u32, bar: u32 },
15 }
16 
17 #[derive(Debug, PartialEq, Eq, Serialize, Deserialize)]
18 #[serde(tag = "type")]
19 enum EnumStructInternally {
20     VariantA { foo: u32, bar: u32, different: u32 },
21     VariantB { foo: u32, bar: u32 },
22 }
23 
24 #[derive(Debug, PartialEq, Eq, Serialize, Deserialize)]
25 #[serde(tag = "type", content = "content")]
26 enum EnumStructAdjacently {
27     VariantA {
28         foo: u32,
29         bar: u32,
30         different: Inner,
31     },
32     VariantB {
33         foo: u32,
34         bar: u32,
35     },
36 }
37 
38 #[derive(Debug, PartialEq, Eq, Serialize, Deserialize)]
39 #[serde(untagged)]
40 enum EnumStructUntagged {
41     VariantA { foo: u32, bar: u32, different: u32 },
42     VariantB { foo: u32, bar: u32 },
43 }
44 
test_ser<T: Serialize>(value: &T, expected: &str)45 fn test_ser<T: Serialize>(value: &T, expected: &str) {
46     let actual = to_string(value).expect("Failed to serialize");
47     assert_eq!(actual, expected);
48 }
49 
test_de<T>(s: &str, expected: T) where T: for<'a> Deserialize<'a> + Debug + PartialEq,50 fn test_de<T>(s: &str, expected: T)
51 where
52     T: for<'a> Deserialize<'a> + Debug + PartialEq,
53 {
54     let actual: Result<T, _> = from_str(s);
55     assert_eq!(actual, Ok(expected));
56 }
57 
test_roundtrip<T>(value: T) where T: Serialize + for<'a> Deserialize<'a> + Debug + PartialEq,58 fn test_roundtrip<T>(value: T)
59 where
60     T: Serialize + for<'a> Deserialize<'a> + Debug + PartialEq,
61 {
62     let s = to_string(&value).expect("Failed to serialize");
63     let actual: Result<T, _> = from_str(&s);
64     assert_eq!(actual, Ok(value));
65 }
66 
67 #[test]
test_externally_a_ser()68 fn test_externally_a_ser() {
69     let v = EnumStructExternally::VariantA {
70         foo: 1,
71         bar: 2,
72         different: 3,
73     };
74     let e = "VariantA(foo:1,bar:2,different:3)";
75     test_ser(&v, e);
76 }
77 
78 #[test]
test_externally_b_ser()79 fn test_externally_b_ser() {
80     let v = EnumStructExternally::VariantB { foo: 1, bar: 2 };
81     let e = "VariantB(foo:1,bar:2)";
82     test_ser(&v, e);
83 }
84 
85 #[test]
test_internally_a_ser()86 fn test_internally_a_ser() {
87     let v = EnumStructInternally::VariantA {
88         foo: 1,
89         bar: 2,
90         different: 3,
91     };
92     let e = "(type:\"VariantA\",foo:1,bar:2,different:3)";
93     test_ser(&v, e);
94 }
95 
96 #[test]
test_internally_b_ser()97 fn test_internally_b_ser() {
98     let v = EnumStructInternally::VariantB { foo: 1, bar: 2 };
99     let e = "(type:\"VariantB\",foo:1,bar:2)";
100     test_ser(&v, e);
101 }
102 
103 #[test]
test_adjacently_a_ser()104 fn test_adjacently_a_ser() {
105     let v = EnumStructAdjacently::VariantA {
106         foo: 1,
107         bar: 2,
108         different: Inner::Foo,
109     };
110     let e = "(type:\"VariantA\",content:(foo:1,bar:2,different:Foo))";
111     test_ser(&v, e);
112 }
113 
114 #[test]
test_adjacently_b_ser()115 fn test_adjacently_b_ser() {
116     let v = EnumStructAdjacently::VariantB { foo: 1, bar: 2 };
117     let e = "(type:\"VariantB\",content:(foo:1,bar:2))";
118     test_ser(&v, e);
119 }
120 
121 #[test]
test_untagged_a_ser()122 fn test_untagged_a_ser() {
123     let v = EnumStructUntagged::VariantA {
124         foo: 1,
125         bar: 2,
126         different: 3,
127     };
128     let e = "(foo:1,bar:2,different:3)";
129     test_ser(&v, e);
130 }
131 
132 #[test]
test_untagged_b_ser()133 fn test_untagged_b_ser() {
134     let v = EnumStructUntagged::VariantB { foo: 1, bar: 2 };
135     let e = "(foo:1,bar:2)";
136     test_ser(&v, e);
137 }
138 
139 #[test]
test_externally_a_de()140 fn test_externally_a_de() {
141     let s = "VariantA(foo:1,bar:2,different:3)";
142     let e = EnumStructExternally::VariantA {
143         foo: 1,
144         bar: 2,
145         different: 3,
146     };
147     test_de(s, e);
148 }
149 
150 #[test]
test_externally_b_de()151 fn test_externally_b_de() {
152     let s = "VariantB(foo:1,bar:2)";
153     let e = EnumStructExternally::VariantB { foo: 1, bar: 2 };
154     test_de(s, e);
155 }
156 
157 #[test]
test_internally_a_de()158 fn test_internally_a_de() {
159     let s = "(type:\"VariantA\",foo:1,bar:2,different:3)";
160     let e = EnumStructInternally::VariantA {
161         foo: 1,
162         bar: 2,
163         different: 3,
164     };
165     test_de(s, e);
166 }
167 
168 #[test]
test_internally_b_de()169 fn test_internally_b_de() {
170     let s = "(type:\"VariantB\",foo:1,bar:2)";
171     let e = EnumStructInternally::VariantB { foo: 1, bar: 2 };
172     test_de(s, e);
173 }
174 
175 #[test]
test_adjacently_a_de()176 fn test_adjacently_a_de() {
177     let s = "(type:\"VariantA\",content:(foo:1,bar:2,different:Foo))";
178     let e = EnumStructAdjacently::VariantA {
179         foo: 1,
180         bar: 2,
181         different: Inner::Foo,
182     };
183     test_de(s, e);
184 }
185 
186 #[test]
test_adjacently_b_de()187 fn test_adjacently_b_de() {
188     let s = "(type:\"VariantB\",content:(foo:1,bar:2))";
189     let e = EnumStructAdjacently::VariantB { foo: 1, bar: 2 };
190     test_de(s, e);
191 }
192 
193 #[test]
test_untagged_a_de()194 fn test_untagged_a_de() {
195     let s = "(foo:1,bar:2,different:3)";
196     let e = EnumStructUntagged::VariantA {
197         foo: 1,
198         bar: 2,
199         different: 3,
200     };
201     test_de(s, e);
202 }
203 
204 #[test]
test_untagged_b_de()205 fn test_untagged_b_de() {
206     let s = "(foo:1,bar:2)";
207     let e = EnumStructUntagged::VariantB { foo: 1, bar: 2 };
208     test_de(s, e);
209 }
210 
211 #[test]
test_externally_a_roundtrip()212 fn test_externally_a_roundtrip() {
213     let v = EnumStructExternally::VariantA {
214         foo: 1,
215         bar: 2,
216         different: 3,
217     };
218     test_roundtrip(v);
219 }
220 
221 #[test]
test_externally_b_roundtrip()222 fn test_externally_b_roundtrip() {
223     let v = EnumStructExternally::VariantB { foo: 1, bar: 2 };
224     test_roundtrip(v);
225 }
226 
227 #[test]
test_internally_a_roundtrip()228 fn test_internally_a_roundtrip() {
229     let v = EnumStructInternally::VariantA {
230         foo: 1,
231         bar: 2,
232         different: 3,
233     };
234     test_roundtrip(v);
235 }
236 
237 #[test]
test_internally_b_roundtrip()238 fn test_internally_b_roundtrip() {
239     let v = EnumStructInternally::VariantB { foo: 1, bar: 2 };
240     test_roundtrip(v);
241 }
242 
243 #[test]
test_adjacently_a_roundtrip()244 fn test_adjacently_a_roundtrip() {
245     let v = EnumStructAdjacently::VariantA {
246         foo: 1,
247         bar: 2,
248         different: Inner::Foo,
249     };
250     test_roundtrip(v);
251 }
252 
253 #[test]
test_adjacently_b_roundtrip()254 fn test_adjacently_b_roundtrip() {
255     let v = EnumStructAdjacently::VariantB { foo: 1, bar: 2 };
256     test_roundtrip(v);
257 }
258 
259 #[test]
test_untagged_a_roundtrip()260 fn test_untagged_a_roundtrip() {
261     let v = EnumStructUntagged::VariantA {
262         foo: 1,
263         bar: 2,
264         different: 3,
265     };
266     test_roundtrip(v);
267 }
268 
269 #[test]
test_untagged_b_roundtrip()270 fn test_untagged_b_roundtrip() {
271     let v = EnumStructUntagged::VariantB { foo: 1, bar: 2 };
272     test_roundtrip(v);
273 }
274