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
    check_from_str_bytes_reader(
478
4
        "\nTupleStruct  \t ( \n 3.5 , \t\n 4.5 \n ) \t\n",
479
4
        Ok(TupleStruct(3.5, 4.5)),
480
    );
481
4
    check_from_str_bytes_reader("\nNewType  \t ( \n 42 \n ) \t\n", Ok(NewType(42)));
482
4
}
483

            
484
#[test]
485
4
fn untagged() {
486
    #[derive(Deserialize, Clone, Debug, PartialEq)]
487
    #[serde(untagged)]
488
    enum Untagged {
489
        U8(u8),
490
        Bool(bool),
491
        Value(crate::Value),
492
    }
493

            
494
4
    check_from_str_bytes_reader("true", Ok(Untagged::Bool(true)));
495
4
    check_from_str_bytes_reader("8", Ok(Untagged::U8(8)));
496

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

            
513
    #[cfg(feature = "internal-span-substring-test")]
514
1
    check_error_span_exclusive::<Untagged>(bogus_struct, expected_err, ")");
515
4
}
516

            
517
#[test]
518
4
fn rename() {
519
    #[derive(Deserialize, Debug, PartialEq)]
520
    enum Foo {
521
        #[serde(rename = "2d")]
522
        D2,
523
        #[serde(rename = "triangle-list")]
524
        TriangleList,
525
    }
526

            
527
4
    check_from_str_bytes_reader("r#2d", Ok(Foo::D2));
528
4
    check_from_str_bytes_reader("r#triangle-list", Ok(Foo::TriangleList));
529
4
}
530

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

            
542
4
    check_from_str_bytes_reader::<(i32, String)>(bogus_struct, expected_err.clone());
543

            
544
    #[cfg(feature = "internal-span-substring-test")]
545
1
    check_error_span_exclusive::<(i32, String)>(bogus_struct, expected_err, "\"");
546
4
}
547

            
548
#[test]
549
4
fn expected_attribute() {
550
4
    check_from_str_bytes_reader::<String>(
551
4
        "#\"Hello\"",
552
4
        err(Error::ExpectedAttribute, (1, 2), (1, 2)),
553
    );
554
4
}
555

            
556
#[test]
557
4
fn expected_attribute_end() {
558
4
    let bogus_struct = "#![enable(unwrap_newtypes) \"Hello\"";
559
4
    let expected_err = err(Error::ExpectedAttributeEnd, (1, 27), (1, 28));
560
4
    check_from_str_bytes_reader::<String>(bogus_struct, expected_err.clone());
561

            
562
    #[cfg(feature = "internal-span-substring-test")]
563
1
    check_error_span_inclusive::<String>(bogus_struct, expected_err, " \"");
564
4
}
565

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

            
576
    #[cfg(feature = "internal-span-substring-test")]
577
1
    check_error_span_exclusive::<String>(bogus_struct, expected_err, "invalid");
578
4
}
579

            
580
#[test]
581
4
fn multiple_attributes() {
582
    #[derive(Debug, Deserialize, PartialEq)]
583
    struct New(String);
584

            
585
4
    check_from_str_bytes_reader(
586
4
        "#![enable(unwrap_newtypes)] #![enable(unwrap_newtypes)] \"Hello\"",
587
4
        Ok(New("Hello".to_owned())),
588
    );
589
4
}
590

            
591
#[test]
592
4
fn type_schema_attributes() {
593
4
    check_from_str_bytes_reader::<String>(
594
4
        "#![type = \"my::Type\"] \"Hello\"",
595
4
        Ok("Hello".to_owned()),
596
    );
597
4
    check_from_str_bytes_reader::<String>(
598
4
        "#![schema = \"./schemas/app.schema.ron\"] \"Hello\"",
599
4
        Ok("Hello".to_owned()),
600
    );
601
4
}
602

            
603
#[test]
604
4
fn mixed_attributes() {
605
    #[derive(Debug, Deserialize, PartialEq)]
606
    struct New(String);
607

            
608
4
    check_from_str_bytes_reader(
609
4
        "#![type = \"my::Type\"] #![enable(unwrap_newtypes)] \"Hello\"",
610
4
        Ok(New("Hello".to_owned())),
611
    );
612
4
}
613

            
614
#[test]
615
4
fn uglified_attribute() {
616
4
    check_from_str_bytes_reader(
617
4
        "#   !\
618
4
    // We definitely want to add a comment here
619
4
    [\t\tenable( // best style ever
620
4
            unwrap_newtypes  ) ] ()",
621
4
        Ok(()),
622
    );
623
4
}
624

            
625
#[test]
626
4
fn implicit_some() {
627
    use serde::de::DeserializeOwned;
628

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

            
632
28
        super::from_str::<Option<T>>(&(enable + s)).unwrap()
633
28
    }
634

            
635
4
    assert_eq!(de("'c'"), Some('c'));
636
4
    assert_eq!(de("5"), Some(5));
637
4
    assert_eq!(de("\"Hello\""), Some("Hello".to_owned()));
638
4
    assert_eq!(de("false"), Some(false));
639
4
    assert_eq!(
640
4
        de("MyStruct(x: .4, y: .5)"),
641
        Some(MyStruct { x: 0.4, y: 0.5 })
642
    );
643

            
644
4
    assert_eq!(de::<char>("None"), None);
645

            
646
    // Not concise
647
4
    assert_eq!(de::<Option<Option<char>>>("None"), None);
648
4
}
649

            
650
#[test]
651
4
fn ws_tuple_newtype_variant() {
652
4
    check_from_str_bytes_reader("B  ( \n true \n ) ", Ok(MyEnum::B(true)));
653
4
}
654

            
655
#[test]
656
4
fn test_byte_stream() {
657
4
    check_from_str_bytes_reader(
658
4
        "BytesStruct( small:[1, 2], large:b\"\\x01\\x02\\x03\\x04\" )",
659
4
        Ok(BytesStruct {
660
4
            small: vec![1, 2],
661
4
            large: vec![1, 2, 3, 4],
662
4
        }),
663
    );
664
4
}
665

            
666
#[test]
667
4
fn test_numbers() {
668
4
    check_from_str_bytes_reader(
669
4
        "[1_234, 12_345, 1_2_3_4_5_6, 1_234_567, 5_55_55_5]",
670
4
        Ok(vec![1234, 12345, 123_456, 1_234_567, 555_555]),
671
    );
672
4
}
673

            
674
100
fn check_de_any_number<
675
100
    T: Copy + PartialEq + core::fmt::Debug + Into<Number> + serde::de::DeserializeOwned,
676
100
>(
677
100
    s: &str,
678
100
    cmp: T,
679
100
) {
680
100
    let mut parser = Parser::new(s).unwrap();
681
100
    let number = parser.any_number().unwrap();
682

            
683
100
    assert_eq!(number, Number::new(cmp));
684
100
    assert_eq!(
685
100
        Number::new(super::from_str::<T>(s).unwrap()),
686
100
        Number::new(cmp)
687
    );
688
100
}
689

            
690
#[test]
691
4
fn test_any_number_precision() {
692
4
    check_de_any_number("1", 1_u8);
693
4
    check_de_any_number("+1", 1_u8);
694
4
    check_de_any_number("-1", -1_i8);
695
4
    check_de_any_number("-1.0", -1.0_f32);
696
4
    check_de_any_number("1.", 1.0_f32);
697
4
    check_de_any_number("-1.", -1.0_f32);
698
4
    check_de_any_number(".3", 0.3_f64);
699
4
    check_de_any_number("-.3", -0.3_f64);
700
4
    check_de_any_number("+.3", 0.3_f64);
701
4
    check_de_any_number("0.3", 0.3_f64);
702
4
    check_de_any_number("NaN", f32::NAN);
703
4
    check_de_any_number("-NaN", -f32::NAN);
704
4
    check_de_any_number("inf", f32::INFINITY);
705
4
    check_de_any_number("-inf", f32::NEG_INFINITY);
706

            
707
    macro_rules! test_min {
708
        ($($ty:ty),*) => {
709
            $(check_de_any_number(&format!("{}", <$ty>::MIN), <$ty>::MIN);)*
710
        };
711
    }
712

            
713
    macro_rules! test_max {
714
        ($($ty:ty),*) => {
715
            $(check_de_any_number(&format!("{}", <$ty>::MAX), <$ty>::MAX);)*
716
        };
717
    }
718

            
719
4
    test_min! { i8, i16, i32, i64, f64 }
720
4
    test_max! { u8, u16, u32, u64, f64 }
721
    #[cfg(feature = "integer128")]
722
2
    test_min! { i128 }
723
    #[cfg(feature = "integer128")]
724
2
    test_max! { u128 }
725
4
}
726

            
727
#[test]
728
4
fn test_value_special_floats() {
729
    use crate::{from_str, value::Number, Value};
730

            
731
4
    assert_eq!(
732
4
        from_str("NaN"),
733
4
        Ok(Value::Number(Number::F32(f32::NAN.into())))
734
    );
735
4
    assert_eq!(
736
4
        from_str("+NaN"),
737
4
        Ok(Value::Number(Number::F32(f32::NAN.into())))
738
    );
739
4
    assert_eq!(
740
4
        from_str("-NaN"),
741
4
        Ok(Value::Number(Number::F32((-f32::NAN).into())))
742
    );
743

            
744
4
    assert_eq!(
745
4
        from_str("inf"),
746
4
        Ok(Value::Number(Number::F32(f32::INFINITY.into())))
747
    );
748
4
    assert_eq!(
749
4
        from_str("+inf"),
750
4
        Ok(Value::Number(Number::F32(f32::INFINITY.into())))
751
    );
752
4
    assert_eq!(
753
4
        from_str("-inf"),
754
4
        Ok(Value::Number(Number::F32(f32::NEG_INFINITY.into())))
755
    );
756
4
}
757

            
758
#[test]
759
4
fn test_leading_whitespace() {
760
4
    check_from_str_bytes_reader("  +1", Ok(1_u8));
761
4
    check_from_str_bytes_reader("  EmptyStruct1", Ok(EmptyStruct1));
762
4
}
763

            
764
304
fn check_from_str_bytes_reader<T: serde::de::DeserializeOwned + PartialEq + core::fmt::Debug>(
765
304
    ron: &str,
766
304
    check: SpannedResult<T>,
767
304
) {
768
304
    let res_str = super::from_str::<T>(ron);
769
304
    assert_eq!(res_str, check);
770

            
771
304
    let res_bytes = super::from_bytes::<T>(ron.as_bytes());
772
304
    assert_eq!(res_bytes, check);
773

            
774
    #[cfg(feature = "std")]
775
    {
776
304
        let res_reader = super::from_reader::<&[u8], T>(ron.as_bytes());
777
304
        assert_eq!(res_reader, check);
778
    }
779
304
}
780

            
781
#[test]
782
4
fn test_remainder() {
783
4
    let mut deserializer = super::Deserializer::from_str("  42  ").unwrap();
784
4
    assert_eq!(
785
4
        <u8 as serde::Deserialize>::deserialize(&mut deserializer).unwrap(),
786
        42
787
    );
788
4
    assert_eq!(deserializer.remainder(), "  ");
789
4
    assert_eq!(deserializer.end(), Ok(()));
790

            
791
4
    let mut deserializer = super::Deserializer::from_str("  42 37 ").unwrap();
792
4
    assert_eq!(
793
4
        <u8 as serde::Deserialize>::deserialize(&mut deserializer).unwrap(),
794
        42
795
    );
796
4
    assert_eq!(deserializer.remainder(), " 37 ");
797
4
    assert_eq!(deserializer.end(), Err(Error::TrailingCharacters));
798
4
}
799

            
800
#[test]
801
4
fn boolean_struct_name() {
802
4
    check_from_str_bytes_reader::<bool>(
803
4
        "true_",
804
4
        Err(SpannedError {
805
4
            code: Error::ExpectedBoolean,
806
4
            span: Span {
807
4
                start: Position { line: 1, col: 1 },
808
4
                end: Position { line: 1, col: 1 },
809
4
            },
810
4
        }),
811
    );
812
4
    check_from_str_bytes_reader::<bool>(
813
4
        "false_",
814
4
        Err(SpannedError {
815
4
            code: Error::ExpectedBoolean,
816
4
            span: Span {
817
4
                start: Position { line: 1, col: 1 },
818
4
                end: Position { line: 1, col: 1 },
819
4
            },
820
4
        }),
821
    );
822
4
}