1
use std::{cmp::PartialEq, fmt::Debug};
2

            
3
use ron::{de::from_str, ser::to_string};
4
use serde::{Deserialize, Serialize};
5

            
6
16
#[derive(Debug, PartialEq, Serialize, Deserialize)]
7
struct Unit;
8

            
9
8
#[derive(Debug, PartialEq, Serialize, Deserialize)]
10
struct Tuple(u8, u8);
11

            
12
16
#[derive(Debug, PartialEq, Serialize, Deserialize)]
13
enum Inner {
14
    Foo,
15
    Bar,
16
}
17

            
18
120
#[derive(Debug, PartialEq, Serialize, Deserialize)]
19
enum EnumStructExternally {
20
    VariantA {
21
        foo: u32,
22
        bar: Unit,
23
        #[serde(with = "ByteStr")]
24
        baz: Vec<u8>,
25
        different: Tuple,
26
    },
27
    VariantB {
28
        foo: u32,
29
        bar: Unit,
30
        #[serde(with = "ByteStr")]
31
        baz: Vec<u8>,
32
    },
33
}
34

            
35
72
#[derive(Debug, PartialEq, Serialize, Deserialize)]
36
#[serde(tag = "type")]
37
enum EnumStructInternally {
38
    VariantA { foo: u32, bar: u32, different: u32 },
39
    VariantB { foo: u32, bar: u32 },
40
}
41

            
42
104
#[derive(Debug, PartialEq, Serialize, Deserialize)]
43
#[serde(tag = "type", content = "content")]
44
enum EnumStructAdjacently {
45
    VariantA { foo: f64, bar: (), different: Inner },
46
    VariantB { foo: f64, bar: () },
47
}
48

            
49
80
#[derive(Debug, PartialEq, Serialize, Deserialize)]
50
#[serde(untagged)]
51
enum EnumStructUntagged {
52
    VariantA { foo: u32, bar: u32, different: u32 },
53
    VariantB { foo: u32, bar: u32 },
54
}
55

            
56
32
fn test_ser<T: Serialize>(value: &T, expected: &str) {
57
32
    let actual = to_string(value).expect("Failed to serialize");
58
32
    assert_eq!(actual, expected);
59
32
}
60

            
61
32
fn test_de<T>(s: &str, expected: T)
62
32
where
63
32
    T: for<'a> Deserialize<'a> + Debug + PartialEq,
64
32
{
65
32
    let actual: Result<T, _> = from_str(s);
66
32
    assert_eq!(actual, Ok(expected));
67
32
}
68

            
69
32
fn test_roundtrip<T>(value: T)
70
32
where
71
32
    T: Serialize + for<'a> Deserialize<'a> + Debug + PartialEq,
72
32
{
73
32
    let s = to_string(&value).expect("Failed to serialize");
74
32
    let actual: Result<T, _> = from_str(&s);
75
32
    assert_eq!(actual, Ok(value));
76
32
}
77

            
78
#[test]
79
4
fn test_externally_a_ser() {
80
4
    let v = EnumStructExternally::VariantA {
81
4
        foo: 1,
82
4
        bar: Unit,
83
4
        baz: vec![b'a'],
84
4
        different: Tuple(2, 3),
85
4
    };
86
4
    let e = "VariantA(foo:1,bar:(),baz:b\"a\",different:(2,3))";
87
4
    test_ser(&v, e);
88
4
}
89

            
90
#[test]
91
4
fn test_externally_b_ser() {
92
4
    let v = EnumStructExternally::VariantB {
93
4
        foo: 1,
94
4
        bar: Unit,
95
4
        baz: vec![b'a'],
96
4
    };
97
4
    let e = "VariantB(foo:1,bar:(),baz:b\"a\")";
98
4
    test_ser(&v, e);
99
4
}
100

            
101
#[test]
102
4
fn test_internally_a_ser() {
103
4
    let v = EnumStructInternally::VariantA {
104
4
        foo: 1,
105
4
        bar: 2,
106
4
        different: 3,
107
4
    };
108
4
    let e = "(type:\"VariantA\",foo:1,bar:2,different:3)";
109
4
    test_ser(&v, e);
110
4
}
111

            
112
#[test]
113
4
fn test_internally_b_ser() {
114
4
    let v = EnumStructInternally::VariantB { foo: 1, bar: 2 };
115
4
    let e = "(type:\"VariantB\",foo:1,bar:2)";
116
4
    test_ser(&v, e);
117
4
}
118

            
119
#[test]
120
4
fn test_adjacently_a_ser() {
121
4
    let v = EnumStructAdjacently::VariantA {
122
4
        foo: 1.0,
123
4
        bar: (),
124
4
        different: Inner::Foo,
125
4
    };
126
4
    let e = "(type:VariantA,content:(foo:1.0,bar:(),different:Foo))";
127
4
    test_ser(&v, e);
128
4
}
129

            
130
#[test]
131
4
fn test_adjacently_b_ser() {
132
4
    let v = EnumStructAdjacently::VariantB { foo: 1.0, bar: () };
133
4
    let e = "(type:VariantB,content:(foo:1.0,bar:()))";
134
4
    test_ser(&v, e);
135
4
}
136

            
137
#[test]
138
4
fn test_untagged_a_ser() {
139
4
    let v = EnumStructUntagged::VariantA {
140
4
        foo: 1,
141
4
        bar: 2,
142
4
        different: 3,
143
4
    };
144
4
    let e = "(foo:1,bar:2,different:3)";
145
4
    test_ser(&v, e);
146
4
}
147

            
148
#[test]
149
4
fn test_untagged_b_ser() {
150
4
    let v = EnumStructUntagged::VariantB { foo: 1, bar: 2 };
151
4
    let e = "(foo:1,bar:2)";
152
4
    test_ser(&v, e);
153
4
}
154

            
155
#[test]
156
4
fn test_externally_a_de() {
157
4
    let s = "VariantA(foo:1,bar:Unit,baz:b\"a\",different:Tuple(2,3))";
158
4
    let e = EnumStructExternally::VariantA {
159
4
        foo: 1,
160
4
        bar: Unit,
161
4
        baz: vec![b'a'],
162
4
        different: Tuple(2, 3),
163
4
    };
164
4
    test_de(s, e);
165
4
}
166

            
167
#[test]
168
4
fn test_externally_b_de() {
169
4
    let s = "VariantB(foo:1,bar:Unit,baz:b\"a\")";
170
4
    let e = EnumStructExternally::VariantB {
171
4
        foo: 1,
172
4
        bar: Unit,
173
4
        baz: vec![b'a'],
174
4
    };
175
4
    test_de(s, e);
176
4
}
177

            
178
#[test]
179
4
fn test_internally_a_de() {
180
4
    let s = "(type:\"VariantA\",foo:1,bar:2,different:3)";
181
4
    let e = EnumStructInternally::VariantA {
182
4
        foo: 1,
183
4
        bar: 2,
184
4
        different: 3,
185
4
    };
186
4
    test_de(s, e);
187
4
}
188

            
189
#[test]
190
4
fn test_internally_b_de() {
191
4
    let s = "(type:\"VariantB\",foo:1,bar:2)";
192
4
    let e = EnumStructInternally::VariantB { foo: 1, bar: 2 };
193
4
    test_de(s, e);
194
4
}
195

            
196
#[test]
197
4
fn test_adjacently_a_de() {
198
4
    let s = "(type:VariantA,content:(foo:1.0,bar:(),different:Foo))";
199
4
    let e = EnumStructAdjacently::VariantA {
200
4
        foo: 1.0,
201
4
        bar: (),
202
4
        different: Inner::Foo,
203
4
    };
204
4
    test_de(s, e);
205
4
}
206

            
207
#[test]
208
4
fn test_adjacently_b_de() {
209
4
    let s = "(type:VariantB,content:(foo:1.0,bar:()))";
210
4
    let e = EnumStructAdjacently::VariantB { foo: 1.0, bar: () };
211
4
    test_de(s, e);
212
4
}
213

            
214
#[test]
215
4
fn test_untagged_a_de() {
216
4
    let s = "(foo:1,bar:2,different:3)";
217
4
    let e = EnumStructUntagged::VariantA {
218
4
        foo: 1,
219
4
        bar: 2,
220
4
        different: 3,
221
4
    };
222
4
    test_de(s, e);
223
4
}
224

            
225
#[test]
226
4
fn test_untagged_b_de() {
227
4
    let s = "(foo:1,bar:2)";
228
4
    let e = EnumStructUntagged::VariantB { foo: 1, bar: 2 };
229
4
    test_de(s, e);
230
4
}
231

            
232
#[test]
233
4
fn test_externally_a_roundtrip() {
234
4
    let v = EnumStructExternally::VariantA {
235
4
        foo: 1,
236
4
        bar: Unit,
237
4
        baz: vec![b'a'],
238
4
        different: Tuple(2, 3),
239
4
    };
240
4
    test_roundtrip(v);
241
4
}
242

            
243
#[test]
244
4
fn test_externally_b_roundtrip() {
245
4
    let v = EnumStructExternally::VariantB {
246
4
        foo: 1,
247
4
        bar: Unit,
248
4
        baz: vec![b'a'],
249
4
    };
250
4
    test_roundtrip(v);
251
4
}
252

            
253
#[test]
254
4
fn test_internally_a_roundtrip() {
255
4
    let v = EnumStructInternally::VariantA {
256
4
        foo: 1,
257
4
        bar: 2,
258
4
        different: 3,
259
4
    };
260
4
    test_roundtrip(v);
261
4
}
262

            
263
#[test]
264
4
fn test_internally_b_roundtrip() {
265
4
    let v = EnumStructInternally::VariantB { foo: 1, bar: 2 };
266
4
    test_roundtrip(v);
267
4
}
268

            
269
#[test]
270
4
fn test_adjacently_a_roundtrip() {
271
4
    let v = EnumStructAdjacently::VariantA {
272
4
        foo: 1.0,
273
4
        bar: (),
274
4
        different: Inner::Foo,
275
4
    };
276
4
    test_roundtrip(v);
277
4
}
278

            
279
#[test]
280
4
fn test_adjacently_b_roundtrip() {
281
4
    let v = EnumStructAdjacently::VariantB { foo: 1.0, bar: () };
282
4
    test_roundtrip(v);
283
4
}
284

            
285
#[test]
286
4
fn test_untagged_a_roundtrip() {
287
4
    let v = EnumStructUntagged::VariantA {
288
4
        foo: 1,
289
4
        bar: 2,
290
4
        different: 3,
291
4
    };
292
4
    test_roundtrip(v);
293
4
}
294

            
295
#[test]
296
4
fn test_untagged_b_roundtrip() {
297
4
    let v = EnumStructUntagged::VariantB { foo: 1, bar: 2 };
298
4
    test_roundtrip(v);
299
4
}
300

            
301
enum ByteStr {}
302

            
303
impl ByteStr {
304
16
    fn serialize<S: serde::Serializer>(data: &[u8], serializer: S) -> Result<S::Ok, S::Error> {
305
16
        serializer.serialize_bytes(data)
306
16
    }
307

            
308
16
    fn deserialize<'de, D: serde::Deserializer<'de>>(deserializer: D) -> Result<Vec<u8>, D::Error> {
309
        struct ByteStrVisitor;
310

            
311
        impl<'de> serde::de::Visitor<'de> for ByteStrVisitor {
312
            type Value = Vec<u8>;
313

            
314
            // GRCOV_EXCL_START
315
            fn expecting(&self, fmt: &mut std::fmt::Formatter) -> std::fmt::Result {
316
                fmt.write_str("a Rusty byte string")
317
            }
318
            // GRCOV_EXCL_STOP
319

            
320
16
            fn visit_bytes<E: serde::de::Error>(self, bytes: &[u8]) -> Result<Self::Value, E> {
321
16
                Ok(bytes.to_vec())
322
16
            }
323
        }
324

            
325
16
        deserializer.deserialize_bytes(ByteStrVisitor)
326
16
    }
327
}