1
use alloc::{
2
    borrow::ToOwned,
3
    format,
4
    string::{String, ToString},
5
    vec,
6
    vec::Vec,
7
};
8

            
9
use serde_bytes;
10
use serde_derive::Deserialize;
11

            
12
use crate::{
13
    error::{Error, Position, Span, SpannedError, SpannedResult},
14
    parse::Parser,
15
    value::Number,
16
};
17

            
18
#[cfg(feature = "internal-span-substring-test")]
19
use crate::util::span_substring::check_error_span_inclusive;
20

            
21
#[cfg(feature = "internal-span-substring-test")]
22
use crate::util::span_substring::check_error_span_exclusive;
23

            
24
#[derive(Debug, PartialEq, Deserialize)]
25
struct EmptyStruct1;
26

            
27
#[derive(Debug, PartialEq, Deserialize)]
28
struct EmptyStruct2 {}
29

            
30
#[derive(Clone, Debug, PartialEq, Deserialize)]
31
struct NewType(i32);
32

            
33
#[derive(Clone, Copy, Debug, PartialEq, Deserialize)]
34
#[serde(rename = "")]
35
struct UnnamedNewType(i32);
36

            
37
#[derive(Debug, PartialEq, Deserialize)]
38
struct TupleStruct(f32, f32);
39

            
40
#[derive(Clone, Debug, PartialEq, Deserialize)]
41
#[serde(rename = "")]
42
struct UnnamedTupleStruct(f32, f32);
43

            
44
#[derive(Clone, Copy, Debug, PartialEq, Deserialize)]
45
struct MyStruct {
46
    x: f32,
47
    y: f32,
48
}
49

            
50
#[derive(Clone, Copy, Debug, PartialEq, Deserialize)]
51
enum MyEnum {
52
    A,
53
    B(bool),
54
    C(bool, f32),
55
    D { a: i32, b: i32 },
56
}
57

            
58
#[derive(Debug, Deserialize, PartialEq)]
59
struct BytesStruct {
60
    small: Vec<u8>,
61
    #[serde(with = "serde_bytes")]
62
    large: Vec<u8>,
63
}
64

            
65
#[test]
66
4
fn test_empty_struct() {
67
4
    check_from_str_bytes_reader("EmptyStruct1", Ok(EmptyStruct1));
68
4
    check_from_str_bytes_reader("EmptyStruct2()", Ok(EmptyStruct2 {}));
69
4
}
70

            
71
#[test]
72
4
fn test_struct() {
73
4
    let my_struct = MyStruct { x: 4.0, y: 7.0 };
74

            
75
4
    check_from_str_bytes_reader("MyStruct(x:4,y:7,)", Ok(my_struct));
76
4
    check_from_str_bytes_reader("(x:4,y:7)", Ok(my_struct));
77

            
78
4
    check_from_str_bytes_reader("NewType(42)", Ok(NewType(42)));
79
4
    check_from_str_bytes_reader("(33)", Ok(NewType(33)));
80

            
81
4
    let bogus_struct = "NewType";
82
4
    let expected_err = Err(SpannedError {
83
4
        code: Error::ExpectedNamedStructLike("NewType"),
84
4
        span: Span {
85
4
            start: Position { line: 1, col: 1 },
86
4
            end: Position { line: 1, col: 8 },
87
4
        },
88
4
    });
89
4
    check_from_str_bytes_reader::<NewType>(bogus_struct, expected_err.clone());
90

            
91
    #[cfg(feature = "internal-span-substring-test")]
92
1
    check_error_span_exclusive::<NewType>(bogus_struct, expected_err, "NewType");
93

            
94
4
    check_from_str_bytes_reader::<UnnamedNewType>(
95
4
        "",
96
4
        Err(SpannedError {
97
4
            code: Error::ExpectedStructLike,
98
4
            span: Span {
99
4
                start: Position { line: 1, col: 1 },
100
4
                end: Position { line: 1, col: 1 },
101
4
            },
102
4
        }),
103
    );
104
4
    check_from_str_bytes_reader("(33)", Ok(UnnamedNewType(33)));
105

            
106
4
    let bogus_struct = "NewType";
107
4
    let expected_err = Err(SpannedError {
108
4
        code: Error::ExpectedNamedStructLike(""),
109
4
        span: Span {
110
4
            start: Position { line: 1, col: 1 },
111
4
            end: Position { line: 1, col: 8 },
112
4
        },
113
4
    });
114

            
115
4
    check_from_str_bytes_reader::<UnnamedNewType>(bogus_struct, expected_err.clone());
116

            
117
    #[cfg(feature = "internal-span-substring-test")]
118
1
    check_error_span_exclusive::<UnnamedNewType>(bogus_struct, expected_err, "NewType");
119

            
120
4
    check_from_str_bytes_reader("TupleStruct(2,5,)", Ok(TupleStruct(2.0, 5.0)));
121
4
    check_from_str_bytes_reader("(3,4)", Ok(TupleStruct(3.0, 4.0)));
122
4
    check_from_str_bytes_reader::<TupleStruct>(
123
4
        "",
124
4
        Err(SpannedError {
125
4
            code: Error::ExpectedNamedStructLike("TupleStruct"),
126
4
            span: Span {
127
4
                start: Position { line: 1, col: 1 },
128
4
                end: Position { line: 1, col: 1 },
129
4
            },
130
4
        }),
131
    );
132

            
133
4
    let bogus_struct = "TupleStruct(2,5,)";
134
4
    let expected_err = Err(SpannedError {
135
4
        code: Error::ExpectedNamedStructLike(""),
136
4
        span: Span {
137
4
            start: Position { line: 1, col: 1 },
138
4
            end: Position { line: 1, col: 12 },
139
4
        },
140
4
    });
141
4
    check_from_str_bytes_reader::<UnnamedTupleStruct>(bogus_struct, expected_err.clone());
142

            
143
    #[cfg(feature = "internal-span-substring-test")]
144
1
    check_error_span_exclusive::<UnnamedTupleStruct>(bogus_struct, expected_err, "TupleStruct");
145

            
146
4
    check_from_str_bytes_reader("(3,4)", Ok(UnnamedTupleStruct(3.0, 4.0)));
147
4
    check_from_str_bytes_reader::<UnnamedTupleStruct>(
148
4
        "",
149
4
        Err(SpannedError {
150
4
            code: Error::ExpectedStructLike,
151
4
            span: Span {
152
4
                start: Position { line: 1, col: 1 },
153
4
                end: Position { line: 1, col: 1 },
154
4
            },
155
4
        }),
156
    );
157
4
}
158

            
159
#[test]
160
4
fn test_unclosed_limited_seq_struct() {
161
    #[derive(Debug, PartialEq)]
162
    struct LimitedStruct;
163

            
164
    impl<'de> serde::Deserialize<'de> for LimitedStruct {
165
12
        fn deserialize<D: serde::Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
166
            struct Visitor;
167

            
168
            impl<'de> serde::de::Visitor<'de> for Visitor {
169
                type Value = LimitedStruct;
170

            
171
                // GRCOV_EXCL_START
172
                fn expecting(&self, fmt: &mut core::fmt::Formatter) -> core::fmt::Result {
173
                    fmt.write_str("struct LimitedStruct")
174
                }
175
                // GRCOV_EXCL_STOP
176

            
177
12
                fn visit_map<A: serde::de::MapAccess<'de>>(
178
12
                    self,
179
12
                    _map: A,
180
12
                ) -> Result<Self::Value, A::Error> {
181
12
                    Ok(LimitedStruct)
182
12
                }
183
            }
184

            
185
12
            deserializer.deserialize_struct("LimitedStruct", &[], Visitor)
186
12
        }
187
    }
188

            
189
4
    check_from_str_bytes_reader::<LimitedStruct>(
190
4
        "(",
191
4
        Err(SpannedError {
192
4
            code: Error::ExpectedStructLikeEnd,
193
4
            span: Span {
194
4
                start: Position { line: 1, col: 1 },
195
4
                end: Position { line: 1, col: 2 },
196
4
            },
197
4
        }),
198
    )
199
4
}
200

            
201
#[test]
202
4
fn test_unclosed_limited_seq() {
203
    #[derive(Debug, PartialEq)]
204
    struct LimitedSeq;
205

            
206
    impl<'de> serde::Deserialize<'de> for LimitedSeq {
207
16
        fn deserialize<D: serde::Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
208
            struct Visitor;
209

            
210
            impl<'de> serde::de::Visitor<'de> for Visitor {
211
                type Value = LimitedSeq;
212

            
213
                // GRCOV_EXCL_START
214
                fn expecting(&self, fmt: &mut core::fmt::Formatter) -> core::fmt::Result {
215
                    fmt.write_str("an empty sequence")
216
                }
217
                // GRCOV_EXCL_STOP
218

            
219
16
                fn visit_seq<A: serde::de::SeqAccess<'de>>(
220
16
                    self,
221
16
                    _seq: A,
222
16
                ) -> Result<Self::Value, A::Error> {
223
16
                    Ok(LimitedSeq)
224
16
                }
225
            }
226

            
227
16
            deserializer.deserialize_seq(Visitor)
228
16
        }
229
    }
230

            
231
4
    check_from_str_bytes_reader::<LimitedSeq>(
232
4
        "[",
233
4
        Err(SpannedError {
234
4
            code: Error::ExpectedArrayEnd,
235
4
            span: Span {
236
4
                start: Position { line: 1, col: 1 },
237
4
                end: Position { line: 1, col: 2 },
238
4
            },
239
4
        }),
240
    );
241

            
242
4
    assert_eq!(
243
4
        crate::Value::from(vec![42]).into_rust::<LimitedSeq>(),
244
4
        Err(Error::ExpectedDifferentLength {
245
4
            expected: String::from("a sequence of length 0"),
246
4
            found: 1
247
4
        })
248
    );
249
4
}
250

            
251
#[test]
252
4
fn test_unclosed_limited_map() {
253
    #[derive(Debug, PartialEq)]
254
    struct LimitedMap;
255

            
256
    impl<'de> serde::Deserialize<'de> for LimitedMap {
257
16
        fn deserialize<D: serde::Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
258
            struct Visitor;
259

            
260
            impl<'de> serde::de::Visitor<'de> for Visitor {
261
                type Value = LimitedMap;
262

            
263
                // GRCOV_EXCL_START
264
                fn expecting(&self, fmt: &mut core::fmt::Formatter) -> core::fmt::Result {
265
                    fmt.write_str("an empty map")
266
                }
267
                // GRCOV_EXCL_STOP
268

            
269
16
                fn visit_map<A: serde::de::MapAccess<'de>>(
270
16
                    self,
271
16
                    _map: A,
272
16
                ) -> Result<Self::Value, A::Error> {
273
16
                    Ok(LimitedMap)
274
16
                }
275
            }
276

            
277
16
            deserializer.deserialize_map(Visitor)
278
16
        }
279
    }
280

            
281
4
    check_from_str_bytes_reader::<LimitedMap>(
282
4
        "{",
283
4
        Err(SpannedError {
284
4
            code: Error::ExpectedMapEnd,
285
4
            span: Span {
286
4
                start: Position { line: 1, col: 1 },
287
4
                end: Position { line: 1, col: 2 },
288
4
            },
289
4
        }),
290
    );
291

            
292
4
    assert_eq!(
293
4
        crate::Value::Map([("a", 42)].into_iter().collect()).into_rust::<LimitedMap>(),
294
4
        Err(Error::ExpectedDifferentLength {
295
4
            expected: String::from("a map of length 0"),
296
4
            found: 1
297
4
        })
298
    );
299
4
}
300

            
301
#[test]
302
4
fn test_option() {
303
4
    check_from_str_bytes_reader("Some(1)", Ok(Some(1u8)));
304
4
    check_from_str_bytes_reader("None", Ok(None::<u8>));
305
4
}
306

            
307
#[test]
308
4
fn test_enum() {
309
4
    check_from_str_bytes_reader("A", Ok(MyEnum::A));
310
4
    check_from_str_bytes_reader("B(true,)", Ok(MyEnum::B(true)));
311
4
    check_from_str_bytes_reader::<MyEnum>(
312
4
        "B",
313
4
        Err(SpannedError {
314
4
            code: Error::ExpectedStructLike,
315
4
            span: Span {
316
4
                start: Position { line: 1, col: 1 },
317
4
                end: Position { line: 1, col: 2 },
318
4
            },
319
4
        }),
320
    );
321
4
    check_from_str_bytes_reader("C(true,3.5,)", Ok(MyEnum::C(true, 3.5)));
322
4
    check_from_str_bytes_reader("D(a:2,b:3,)", Ok(MyEnum::D { a: 2, b: 3 }));
323
4
}
324

            
325
#[test]
326
4
fn test_array() {
327
4
    check_from_str_bytes_reader::<[i32; 0]>("()", Ok([]));
328
4
    check_from_str_bytes_reader("[]", Ok(Vec::<i32>::new()));
329

            
330
4
    check_from_str_bytes_reader("(2,3,4,)", Ok([2, 3, 4i32]));
331
4
    check_from_str_bytes_reader("[2,3,4,]", Ok([2, 3, 4i32].to_vec()));
332
4
}
333

            
334
#[cfg(feature = "std")]
335
#[test]
336
4
fn test_map() {
337
    use std::collections::HashMap;
338

            
339
4
    let mut map = HashMap::new();
340
4
    map.insert((true, false), 4);
341
4
    map.insert((false, false), 123);
342

            
343
4
    check_from_str_bytes_reader(
344
4
        "{
345
4
        (true,false,):4,
346
4
        (false,false,):123,
347
4
    }",
348
4
        Ok(map),
349
    );
350
4
}
351

            
352
#[test]
353
4
fn test_string() {
354
4
    check_from_str_bytes_reader("\"String\"", Ok(String::from("String")));
355

            
356
4
    check_from_str_bytes_reader("r\"String\"", Ok(String::from("String")));
357
4
    check_from_str_bytes_reader("r#\"String\"#", Ok(String::from("String")));
358

            
359
4
    check_from_str_bytes_reader(
360
4
        "r#\"String with\nmultiple\nlines\n\"#",
361
4
        Ok(String::from("String with\nmultiple\nlines\n")),
362
    );
363

            
364
4
    check_from_str_bytes_reader(
365
4
        "r##\"String with \"#\"##",
366
4
        Ok(String::from("String with \"#")),
367
    );
368
4
}
369

            
370
#[test]
371
4
fn test_char() {
372
4
    check_from_str_bytes_reader("'c'", Ok('c'));
373
4
}
374

            
375
#[test]
376
4
fn test_escape_char() {
377
4
    check_from_str_bytes_reader("'\\''", Ok('\''));
378
4
}
379

            
380
#[test]
381
4
fn test_escape() {
382
4
    check_from_str_bytes_reader(r#""\"Quoted\"""#, Ok(String::from("\"Quoted\"")));
383
4
}
384

            
385
#[test]
386
4
fn test_comment() {
387
4
    check_from_str_bytes_reader(
388
4
        "(
389
4
x: 1.0, // x is just 1
390
4
// There is another comment in the very next line..
391
4
// And y is indeed
392
4
y: 2.0 // 2!
393
4
    )",
394
4
        Ok(MyStruct { x: 1.0, y: 2.0 }),
395
    );
396
4
}
397

            
398
60
fn err<T>(
399
60
    kind: Error,
400
60
    (line_start, col_start): (usize, usize),
401
60
    (line_end, col_end): (usize, usize),
402
60
) -> SpannedResult<T> {
403
60
    Err(SpannedError {
404
60
        code: kind,
405
60
        span: Span {
406
60
            start: Position {
407
60
                line: line_start,
408
60
                col: col_start,
409
60
            },
410
60
            end: Position {
411
60
                line: line_end,
412
60
                col: col_end,
413
60
            },
414
60
        },
415
60
    })
416
60
}
417

            
418
#[test]
419
4
fn test_err_wrong_value() {
420
    #[cfg(feature = "std")]
421
    use std::collections::HashMap;
422

            
423
4
    check_from_str_bytes_reader::<f32>("'c'", err(Error::ExpectedFloat, (1, 1), (1, 1)));
424
4
    check_from_str_bytes_reader::<String>("'c'", err(Error::ExpectedString, (1, 1), (1, 1)));
425
    #[cfg(feature = "std")]
426
4
    check_from_str_bytes_reader::<HashMap<u32, u32>>(
427
4
        "'c'",
428
4
        err(Error::ExpectedMap, (1, 1), (1, 1)),
429
    );
430
4
    check_from_str_bytes_reader::<[u8; 5]>("'c'", err(Error::ExpectedStructLike, (1, 1), (1, 1)));
431
4
    check_from_str_bytes_reader::<Vec<u32>>("'c'", err(Error::ExpectedArray, (1, 1), (1, 1)));
432
4
    check_from_str_bytes_reader::<MyEnum>("'c'", err(Error::ExpectedIdentifier, (1, 1), (1, 1)));
433
4
    check_from_str_bytes_reader::<MyStruct>(
434
4
        "'c'",
435
4
        err(Error::ExpectedNamedStructLike("MyStruct"), (1, 1), (1, 1)),
436
    );
437
4
    check_from_str_bytes_reader::<MyStruct>(
438
4
        "NotMyStruct(x: 4, y: 2)",
439
4
        err(
440
4
            Error::ExpectedDifferentStructName {
441
4
                expected: "MyStruct",
442
4
                found: String::from("NotMyStruct"),
443
4
            },
444
4
            (1, 1),
445
4
            (1, 12),
446
        ),
447
    );
448
4
    check_from_str_bytes_reader::<(u8, bool)>(
449
4
        "'c'",
450
4
        err(Error::ExpectedStructLike, (1, 1), (1, 1)),
451
    );
452
4
    check_from_str_bytes_reader::<bool>("notabool", err(Error::ExpectedBoolean, (1, 1), (1, 1)));
453

            
454
4
    let bogus_struct = "MyStruct(\n    x: true)";
455
4
    let expected_err = err(Error::ExpectedFloat, (2, 7), (2, 8));
456

            
457
4
    check_from_str_bytes_reader::<MyStruct>(bogus_struct, expected_err.clone());
458

            
459
    #[cfg(feature = "internal-span-substring-test")]
460
1
    check_error_span_inclusive::<MyStruct>(bogus_struct, expected_err, " t");
461

            
462
4
    let bogus_struct = "MyStruct(\n    x: 3.5, \n    y:)";
463
4
    let expected_err = err(Error::ExpectedFloat, (3, 7), (3, 7));
464

            
465
4
    check_from_str_bytes_reader::<MyStruct>(bogus_struct, expected_err.clone());
466

            
467
    #[cfg(feature = "internal-span-substring-test")]
468
1
    check_error_span_inclusive::<MyStruct>(bogus_struct, expected_err, ")");
469
4
}
470

            
471
#[test]
472
4
fn test_perm_ws() {
473
4
    check_from_str_bytes_reader(
474
4
        "\nMyStruct  \t ( \n x   : 3.5 , \t y\n: 4.5 \n ) \t\n",
475
4
        Ok(MyStruct { x: 3.5, y: 4.5 }),
476
    );
477
4
}
478

            
479
#[test]
480
4
fn untagged() {
481
    #[derive(Deserialize, Clone, Debug, PartialEq)]
482
    #[serde(untagged)]
483
    enum Untagged {
484
        U8(u8),
485
        Bool(bool),
486
        Value(crate::Value),
487
    }
488

            
489
4
    check_from_str_bytes_reader("true", Ok(Untagged::Bool(true)));
490
4
    check_from_str_bytes_reader("8", Ok(Untagged::U8(8)));
491

            
492
    // Check for a failure in Deserializer::check_struct_type
493
    // - untagged enum and a leading identifier trigger the serde content enum path
494
    // - serde content uses deserialize_any, which retriggers the struct type check
495
    // - struct type check inside a serde content performs a full newtype check
496
    // - newtype check fails on the unclosed struct
497
    //
498
4
    let bogus_struct = "Value(()";
499
4
    let expected_err = Err(crate::error::SpannedError {
500
4
        code: crate::Error::Eof,
501
4
        span: Span {
502
4
            start: Position { line: 1, col: 8 },
503
4
            end: crate::error::Position { line: 1, col: 9 },
504
4
        },
505
4
    });
506
4
    check_from_str_bytes_reader::<Untagged>(bogus_struct, expected_err.clone());
507

            
508
    #[cfg(feature = "internal-span-substring-test")]
509
1
    check_error_span_exclusive::<Untagged>(bogus_struct, expected_err, ")");
510
4
}
511

            
512
#[test]
513
4
fn rename() {
514
    #[derive(Deserialize, Debug, PartialEq)]
515
    enum Foo {
516
        #[serde(rename = "2d")]
517
        D2,
518
        #[serde(rename = "triangle-list")]
519
        TriangleList,
520
    }
521

            
522
4
    check_from_str_bytes_reader("r#2d", Ok(Foo::D2));
523
4
    check_from_str_bytes_reader("r#triangle-list", Ok(Foo::TriangleList));
524
4
}
525

            
526
#[test]
527
4
fn forgot_apostrophes() {
528
4
    let bogus_struct = "(4, \"Hello)";
529
4
    let expected_err = Err(SpannedError {
530
4
        code: Error::ExpectedStringEnd,
531
4
        span: Span {
532
4
            start: Position { line: 1, col: 5 },
533
4
            end: Position { line: 1, col: 6 },
534
4
        },
535
4
    });
536

            
537
4
    check_from_str_bytes_reader::<(i32, String)>(bogus_struct, expected_err.clone());
538

            
539
    #[cfg(feature = "internal-span-substring-test")]
540
1
    check_error_span_exclusive::<(i32, String)>(bogus_struct, expected_err, "\"");
541
4
}
542

            
543
#[test]
544
4
fn expected_attribute() {
545
4
    check_from_str_bytes_reader::<String>(
546
4
        "#\"Hello\"",
547
4
        err(Error::ExpectedAttribute, (1, 2), (1, 2)),
548
    );
549
4
}
550

            
551
#[test]
552
4
fn expected_attribute_end() {
553
4
    let bogus_struct = "#![enable(unwrap_newtypes) \"Hello\"";
554
4
    let expected_err = err(Error::ExpectedAttributeEnd, (1, 27), (1, 28));
555
4
    check_from_str_bytes_reader::<String>(bogus_struct, expected_err.clone());
556

            
557
    #[cfg(feature = "internal-span-substring-test")]
558
1
    check_error_span_inclusive::<String>(bogus_struct, expected_err, " \"");
559
4
}
560

            
561
#[test]
562
4
fn invalid_attribute() {
563
4
    let bogus_struct = "#![enable(invalid)] \"Hello\"";
564
4
    let expected_err = err(
565
4
        Error::NoSuchExtension("invalid".to_string()),
566
4
        (1, 11),
567
4
        (1, 18),
568
    );
569
4
    check_from_str_bytes_reader::<String>(bogus_struct, expected_err.clone());
570

            
571
    #[cfg(feature = "internal-span-substring-test")]
572
1
    check_error_span_exclusive::<String>(bogus_struct, expected_err, "invalid");
573
4
}
574

            
575
#[test]
576
4
fn multiple_attributes() {
577
    #[derive(Debug, Deserialize, PartialEq)]
578
    struct New(String);
579

            
580
4
    check_from_str_bytes_reader(
581
4
        "#![enable(unwrap_newtypes)] #![enable(unwrap_newtypes)] \"Hello\"",
582
4
        Ok(New("Hello".to_owned())),
583
    );
584
4
}
585

            
586
#[test]
587
4
fn uglified_attribute() {
588
4
    check_from_str_bytes_reader(
589
4
        "#   !\
590
4
    // We definitely want to add a comment here
591
4
    [\t\tenable( // best style ever
592
4
            unwrap_newtypes  ) ] ()",
593
4
        Ok(()),
594
    );
595
4
}
596

            
597
#[test]
598
4
fn implicit_some() {
599
    use serde::de::DeserializeOwned;
600

            
601
28
    fn de<T: DeserializeOwned>(s: &str) -> Option<T> {
602
28
        let enable = "#![enable(implicit_some)]\n".to_string();
603

            
604
28
        super::from_str::<Option<T>>(&(enable + s)).unwrap()
605
28
    }
606

            
607
4
    assert_eq!(de("'c'"), Some('c'));
608
4
    assert_eq!(de("5"), Some(5));
609
4
    assert_eq!(de("\"Hello\""), Some("Hello".to_owned()));
610
4
    assert_eq!(de("false"), Some(false));
611
4
    assert_eq!(
612
4
        de("MyStruct(x: .4, y: .5)"),
613
        Some(MyStruct { x: 0.4, y: 0.5 })
614
    );
615

            
616
4
    assert_eq!(de::<char>("None"), None);
617

            
618
    // Not concise
619
4
    assert_eq!(de::<Option<Option<char>>>("None"), None);
620
4
}
621

            
622
#[test]
623
4
fn ws_tuple_newtype_variant() {
624
4
    check_from_str_bytes_reader("B  ( \n true \n ) ", Ok(MyEnum::B(true)));
625
4
}
626

            
627
#[test]
628
4
fn test_byte_stream() {
629
4
    check_from_str_bytes_reader(
630
4
        "BytesStruct( small:[1, 2], large:b\"\\x01\\x02\\x03\\x04\" )",
631
4
        Ok(BytesStruct {
632
4
            small: vec![1, 2],
633
4
            large: vec![1, 2, 3, 4],
634
4
        }),
635
    );
636
4
}
637

            
638
#[test]
639
4
fn test_numbers() {
640
4
    check_from_str_bytes_reader(
641
4
        "[1_234, 12_345, 1_2_3_4_5_6, 1_234_567, 5_55_55_5]",
642
4
        Ok(vec![1234, 12345, 123_456, 1_234_567, 555_555]),
643
    );
644
4
}
645

            
646
100
fn check_de_any_number<
647
100
    T: Copy + PartialEq + core::fmt::Debug + Into<Number> + serde::de::DeserializeOwned,
648
100
>(
649
100
    s: &str,
650
100
    cmp: T,
651
100
) {
652
100
    let mut parser = Parser::new(s).unwrap();
653
100
    let number = parser.any_number().unwrap();
654

            
655
100
    assert_eq!(number, Number::new(cmp));
656
100
    assert_eq!(
657
100
        Number::new(super::from_str::<T>(s).unwrap()),
658
100
        Number::new(cmp)
659
    );
660
100
}
661

            
662
#[test]
663
4
fn test_any_number_precision() {
664
4
    check_de_any_number("1", 1_u8);
665
4
    check_de_any_number("+1", 1_u8);
666
4
    check_de_any_number("-1", -1_i8);
667
4
    check_de_any_number("-1.0", -1.0_f32);
668
4
    check_de_any_number("1.", 1.0_f32);
669
4
    check_de_any_number("-1.", -1.0_f32);
670
4
    check_de_any_number(".3", 0.3_f64);
671
4
    check_de_any_number("-.3", -0.3_f64);
672
4
    check_de_any_number("+.3", 0.3_f64);
673
4
    check_de_any_number("0.3", 0.3_f64);
674
4
    check_de_any_number("NaN", f32::NAN);
675
4
    check_de_any_number("-NaN", -f32::NAN);
676
4
    check_de_any_number("inf", f32::INFINITY);
677
4
    check_de_any_number("-inf", f32::NEG_INFINITY);
678

            
679
    macro_rules! test_min {
680
        ($($ty:ty),*) => {
681
            $(check_de_any_number(&format!("{}", <$ty>::MIN), <$ty>::MIN);)*
682
        };
683
    }
684

            
685
    macro_rules! test_max {
686
        ($($ty:ty),*) => {
687
            $(check_de_any_number(&format!("{}", <$ty>::MAX), <$ty>::MAX);)*
688
        };
689
    }
690

            
691
4
    test_min! { i8, i16, i32, i64, f64 }
692
4
    test_max! { u8, u16, u32, u64, f64 }
693
    #[cfg(feature = "integer128")]
694
2
    test_min! { i128 }
695
    #[cfg(feature = "integer128")]
696
2
    test_max! { u128 }
697
4
}
698

            
699
#[test]
700
4
fn test_value_special_floats() {
701
    use crate::{from_str, value::Number, Value};
702

            
703
4
    assert_eq!(
704
4
        from_str("NaN"),
705
4
        Ok(Value::Number(Number::F32(f32::NAN.into())))
706
    );
707
4
    assert_eq!(
708
4
        from_str("+NaN"),
709
4
        Ok(Value::Number(Number::F32(f32::NAN.into())))
710
    );
711
4
    assert_eq!(
712
4
        from_str("-NaN"),
713
4
        Ok(Value::Number(Number::F32((-f32::NAN).into())))
714
    );
715

            
716
4
    assert_eq!(
717
4
        from_str("inf"),
718
4
        Ok(Value::Number(Number::F32(f32::INFINITY.into())))
719
    );
720
4
    assert_eq!(
721
4
        from_str("+inf"),
722
4
        Ok(Value::Number(Number::F32(f32::INFINITY.into())))
723
    );
724
4
    assert_eq!(
725
4
        from_str("-inf"),
726
4
        Ok(Value::Number(Number::F32(f32::NEG_INFINITY.into())))
727
    );
728
4
}
729

            
730
#[test]
731
4
fn test_leading_whitespace() {
732
4
    check_from_str_bytes_reader("  +1", Ok(1_u8));
733
4
    check_from_str_bytes_reader("  EmptyStruct1", Ok(EmptyStruct1));
734
4
}
735

            
736
284
fn check_from_str_bytes_reader<T: serde::de::DeserializeOwned + PartialEq + core::fmt::Debug>(
737
284
    ron: &str,
738
284
    check: SpannedResult<T>,
739
284
) {
740
284
    let res_str = super::from_str::<T>(ron);
741
284
    assert_eq!(res_str, check);
742

            
743
284
    let res_bytes = super::from_bytes::<T>(ron.as_bytes());
744
284
    assert_eq!(res_bytes, check);
745

            
746
    #[cfg(feature = "std")]
747
    {
748
284
        let res_reader = super::from_reader::<&[u8], T>(ron.as_bytes());
749
284
        assert_eq!(res_reader, check);
750
    }
751
284
}
752

            
753
#[test]
754
4
fn test_remainder() {
755
4
    let mut deserializer = super::Deserializer::from_str("  42  ").unwrap();
756
4
    assert_eq!(
757
4
        <u8 as serde::Deserialize>::deserialize(&mut deserializer).unwrap(),
758
        42
759
    );
760
4
    assert_eq!(deserializer.remainder(), "  ");
761
4
    assert_eq!(deserializer.end(), Ok(()));
762

            
763
4
    let mut deserializer = super::Deserializer::from_str("  42 37 ").unwrap();
764
4
    assert_eq!(
765
4
        <u8 as serde::Deserialize>::deserialize(&mut deserializer).unwrap(),
766
        42
767
    );
768
4
    assert_eq!(deserializer.remainder(), " 37 ");
769
4
    assert_eq!(deserializer.end(), Err(Error::TrailingCharacters));
770
4
}
771

            
772
#[test]
773
4
fn boolean_struct_name() {
774
4
    check_from_str_bytes_reader::<bool>(
775
4
        "true_",
776
4
        Err(SpannedError {
777
4
            code: Error::ExpectedBoolean,
778
4
            span: Span {
779
4
                start: Position { line: 1, col: 1 },
780
4
                end: Position { line: 1, col: 1 },
781
4
            },
782
4
        }),
783
    );
784
4
    check_from_str_bytes_reader::<bool>(
785
4
        "false_",
786
4
        Err(SpannedError {
787
4
            code: Error::ExpectedBoolean,
788
4
            span: Span {
789
4
                start: Position { line: 1, col: 1 },
790
4
                end: Position { line: 1, col: 1 },
791
4
            },
792
4
        }),
793
    );
794
4
}