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, SpannedError, SpannedResult},
14
    parse::Parser,
15
    value::Number,
16
};
17

            
18
#[derive(Debug, PartialEq, Deserialize)]
19
struct EmptyStruct1;
20

            
21
#[derive(Debug, PartialEq, Deserialize)]
22
struct EmptyStruct2 {}
23

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

            
27
#[derive(Debug, PartialEq, Deserialize)]
28
#[serde(rename = "")]
29
struct UnnamedNewType(i32);
30

            
31
#[derive(Debug, PartialEq, Deserialize)]
32
struct TupleStruct(f32, f32);
33

            
34
#[derive(Debug, PartialEq, Deserialize)]
35
#[serde(rename = "")]
36
struct UnnamedTupleStruct(f32, f32);
37

            
38
#[derive(Clone, Copy, Debug, PartialEq, Deserialize)]
39
struct MyStruct {
40
    x: f32,
41
    y: f32,
42
}
43

            
44
#[derive(Clone, Copy, Debug, PartialEq, Deserialize)]
45
enum MyEnum {
46
    A,
47
    B(bool),
48
    C(bool, f32),
49
    D { a: i32, b: i32 },
50
}
51

            
52
#[derive(Debug, Deserialize, PartialEq)]
53
struct BytesStruct {
54
    small: Vec<u8>,
55
    #[serde(with = "serde_bytes")]
56
    large: Vec<u8>,
57
}
58

            
59
#[test]
60
4
fn test_empty_struct() {
61
4
    check_from_str_bytes_reader("EmptyStruct1", Ok(EmptyStruct1));
62
4
    check_from_str_bytes_reader("EmptyStruct2()", Ok(EmptyStruct2 {}));
63
4
}
64

            
65
#[test]
66
4
fn test_struct() {
67
4
    let my_struct = MyStruct { x: 4.0, y: 7.0 };
68
4

            
69
4
    check_from_str_bytes_reader("MyStruct(x:4,y:7,)", Ok(my_struct));
70
4
    check_from_str_bytes_reader("(x:4,y:7)", Ok(my_struct));
71
4

            
72
4
    check_from_str_bytes_reader("NewType(42)", Ok(NewType(42)));
73
4
    check_from_str_bytes_reader("(33)", Ok(NewType(33)));
74
4

            
75
4
    check_from_str_bytes_reader::<NewType>(
76
4
        "NewType",
77
4
        Err(SpannedError {
78
4
            code: Error::ExpectedNamedStructLike("NewType"),
79
4
            position: Position { line: 1, col: 8 },
80
4
        }),
81
4
    );
82
4
    check_from_str_bytes_reader::<UnnamedNewType>(
83
4
        "",
84
4
        Err(SpannedError {
85
4
            code: Error::ExpectedStructLike,
86
4
            position: Position { line: 1, col: 1 },
87
4
        }),
88
4
    );
89
4
    check_from_str_bytes_reader("(33)", Ok(UnnamedNewType(33)));
90
4
    check_from_str_bytes_reader::<UnnamedNewType>(
91
4
        "Newtype",
92
4
        Err(SpannedError {
93
4
            code: Error::ExpectedNamedStructLike(""),
94
4
            position: Position { line: 1, col: 8 },
95
4
        }),
96
4
    );
97
4

            
98
4
    check_from_str_bytes_reader("TupleStruct(2,5,)", Ok(TupleStruct(2.0, 5.0)));
99
4
    check_from_str_bytes_reader("(3,4)", Ok(TupleStruct(3.0, 4.0)));
100
4
    check_from_str_bytes_reader::<TupleStruct>(
101
4
        "",
102
4
        Err(SpannedError {
103
4
            code: Error::ExpectedNamedStructLike("TupleStruct"),
104
4
            position: Position { line: 1, col: 1 },
105
4
        }),
106
4
    );
107
4
    check_from_str_bytes_reader::<UnnamedTupleStruct>(
108
4
        "TupleStruct(2,5,)",
109
4
        Err(SpannedError {
110
4
            code: Error::ExpectedNamedStructLike(""),
111
4
            position: Position { line: 1, col: 12 },
112
4
        }),
113
4
    );
114
4
    check_from_str_bytes_reader("(3,4)", Ok(UnnamedTupleStruct(3.0, 4.0)));
115
4
    check_from_str_bytes_reader::<UnnamedTupleStruct>(
116
4
        "",
117
4
        Err(SpannedError {
118
4
            code: Error::ExpectedStructLike,
119
4
            position: Position { line: 1, col: 1 },
120
4
        }),
121
4
    );
122
4
}
123

            
124
#[test]
125
4
fn test_unclosed_limited_seq_struct() {
126
    #[derive(Debug, PartialEq)]
127
    struct LimitedStruct;
128

            
129
    impl<'de> serde::Deserialize<'de> for LimitedStruct {
130
12
        fn deserialize<D: serde::Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
131
            struct Visitor;
132

            
133
            impl<'de> serde::de::Visitor<'de> for Visitor {
134
                type Value = LimitedStruct;
135

            
136
                // GRCOV_EXCL_START
137
                fn expecting(&self, fmt: &mut core::fmt::Formatter) -> core::fmt::Result {
138
                    fmt.write_str("struct LimitedStruct")
139
                }
140
                // GRCOV_EXCL_STOP
141

            
142
12
                fn visit_map<A: serde::de::MapAccess<'de>>(
143
12
                    self,
144
12
                    _map: A,
145
12
                ) -> Result<Self::Value, A::Error> {
146
12
                    Ok(LimitedStruct)
147
12
                }
148
            }
149

            
150
12
            deserializer.deserialize_struct("LimitedStruct", &[], Visitor)
151
12
        }
152
    }
153

            
154
4
    check_from_str_bytes_reader::<LimitedStruct>(
155
4
        "(",
156
4
        Err(SpannedError {
157
4
            code: Error::ExpectedStructLikeEnd,
158
4
            position: Position { line: 1, col: 2 },
159
4
        }),
160
4
    )
161
4
}
162

            
163
#[test]
164
4
fn test_unclosed_limited_seq() {
165
    #[derive(Debug, PartialEq)]
166
    struct LimitedSeq;
167

            
168
    impl<'de> serde::Deserialize<'de> for LimitedSeq {
169
16
        fn deserialize<D: serde::Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
170
            struct Visitor;
171

            
172
            impl<'de> serde::de::Visitor<'de> for Visitor {
173
                type Value = LimitedSeq;
174

            
175
                // GRCOV_EXCL_START
176
                fn expecting(&self, fmt: &mut core::fmt::Formatter) -> core::fmt::Result {
177
                    fmt.write_str("an empty sequence")
178
                }
179
                // GRCOV_EXCL_STOP
180

            
181
16
                fn visit_seq<A: serde::de::SeqAccess<'de>>(
182
16
                    self,
183
16
                    _seq: A,
184
16
                ) -> Result<Self::Value, A::Error> {
185
16
                    Ok(LimitedSeq)
186
16
                }
187
            }
188

            
189
16
            deserializer.deserialize_seq(Visitor)
190
16
        }
191
    }
192

            
193
4
    check_from_str_bytes_reader::<LimitedSeq>(
194
4
        "[",
195
4
        Err(SpannedError {
196
4
            code: Error::ExpectedArrayEnd,
197
4
            position: Position { line: 1, col: 2 },
198
4
        }),
199
4
    );
200
4

            
201
4
    assert_eq!(
202
4
        crate::Value::from(vec![42]).into_rust::<LimitedSeq>(),
203
4
        Err(Error::ExpectedDifferentLength {
204
4
            expected: String::from("a sequence of length 0"),
205
4
            found: 1
206
4
        })
207
4
    );
208
4
}
209

            
210
#[test]
211
4
fn test_unclosed_limited_map() {
212
    #[derive(Debug, PartialEq)]
213
    struct LimitedMap;
214

            
215
    impl<'de> serde::Deserialize<'de> for LimitedMap {
216
16
        fn deserialize<D: serde::Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
217
            struct Visitor;
218

            
219
            impl<'de> serde::de::Visitor<'de> for Visitor {
220
                type Value = LimitedMap;
221

            
222
                // GRCOV_EXCL_START
223
                fn expecting(&self, fmt: &mut core::fmt::Formatter) -> core::fmt::Result {
224
                    fmt.write_str("an empty map")
225
                }
226
                // GRCOV_EXCL_STOP
227

            
228
16
                fn visit_map<A: serde::de::MapAccess<'de>>(
229
16
                    self,
230
16
                    _map: A,
231
16
                ) -> Result<Self::Value, A::Error> {
232
16
                    Ok(LimitedMap)
233
16
                }
234
            }
235

            
236
16
            deserializer.deserialize_map(Visitor)
237
16
        }
238
    }
239

            
240
4
    check_from_str_bytes_reader::<LimitedMap>(
241
4
        "{",
242
4
        Err(SpannedError {
243
4
            code: Error::ExpectedMapEnd,
244
4
            position: Position { line: 1, col: 2 },
245
4
        }),
246
4
    );
247
4

            
248
4
    assert_eq!(
249
4
        crate::Value::Map([("a", 42)].into_iter().collect()).into_rust::<LimitedMap>(),
250
4
        Err(Error::ExpectedDifferentLength {
251
4
            expected: String::from("a map of length 0"),
252
4
            found: 1
253
4
        })
254
4
    );
255
4
}
256

            
257
#[test]
258
4
fn test_option() {
259
4
    check_from_str_bytes_reader("Some(1)", Ok(Some(1u8)));
260
4
    check_from_str_bytes_reader("None", Ok(None::<u8>));
261
4
}
262

            
263
#[test]
264
4
fn test_enum() {
265
4
    check_from_str_bytes_reader("A", Ok(MyEnum::A));
266
4
    check_from_str_bytes_reader("B(true,)", Ok(MyEnum::B(true)));
267
4
    check_from_str_bytes_reader::<MyEnum>(
268
4
        "B",
269
4
        Err(SpannedError {
270
4
            code: Error::ExpectedStructLike,
271
4
            position: Position { line: 1, col: 2 },
272
4
        }),
273
4
    );
274
4
    check_from_str_bytes_reader("C(true,3.5,)", Ok(MyEnum::C(true, 3.5)));
275
4
    check_from_str_bytes_reader("D(a:2,b:3,)", Ok(MyEnum::D { a: 2, b: 3 }));
276
4
}
277

            
278
#[test]
279
4
fn test_array() {
280
4
    check_from_str_bytes_reader::<[i32; 0]>("()", Ok([]));
281
4
    check_from_str_bytes_reader("[]", Ok(Vec::<i32>::new()));
282
4

            
283
4
    check_from_str_bytes_reader("(2,3,4,)", Ok([2, 3, 4i32]));
284
4
    check_from_str_bytes_reader("[2,3,4,]", Ok([2, 3, 4i32].to_vec()));
285
4
}
286

            
287
#[cfg(feature = "std")]
288
#[test]
289
4
fn test_map() {
290
    use std::collections::HashMap;
291

            
292
4
    let mut map = HashMap::new();
293
4
    map.insert((true, false), 4);
294
4
    map.insert((false, false), 123);
295
4

            
296
4
    check_from_str_bytes_reader(
297
4
        "{
298
4
        (true,false,):4,
299
4
        (false,false,):123,
300
4
    }",
301
4
        Ok(map),
302
4
    );
303
4
}
304

            
305
#[test]
306
4
fn test_string() {
307
4
    check_from_str_bytes_reader("\"String\"", Ok(String::from("String")));
308
4

            
309
4
    check_from_str_bytes_reader("r\"String\"", Ok(String::from("String")));
310
4
    check_from_str_bytes_reader("r#\"String\"#", Ok(String::from("String")));
311
4

            
312
4
    check_from_str_bytes_reader(
313
4
        "r#\"String with\nmultiple\nlines\n\"#",
314
4
        Ok(String::from("String with\nmultiple\nlines\n")),
315
4
    );
316
4

            
317
4
    check_from_str_bytes_reader(
318
4
        "r##\"String with \"#\"##",
319
4
        Ok(String::from("String with \"#")),
320
4
    );
321
4
}
322

            
323
#[test]
324
4
fn test_char() {
325
4
    check_from_str_bytes_reader("'c'", Ok('c'));
326
4
}
327

            
328
#[test]
329
4
fn test_escape_char() {
330
4
    check_from_str_bytes_reader("'\\''", Ok('\''));
331
4
}
332

            
333
#[test]
334
4
fn test_escape() {
335
4
    check_from_str_bytes_reader(r#""\"Quoted\"""#, Ok(String::from("\"Quoted\"")));
336
4
}
337

            
338
#[test]
339
4
fn test_comment() {
340
4
    check_from_str_bytes_reader(
341
4
        "(
342
4
x: 1.0, // x is just 1
343
4
// There is another comment in the very next line..
344
4
// And y is indeed
345
4
y: 2.0 // 2!
346
4
    )",
347
4
        Ok(MyStruct { x: 1.0, y: 2.0 }),
348
4
    );
349
4
}
350

            
351
60
fn err<T>(kind: Error, line: usize, col: usize) -> SpannedResult<T> {
352
60
    Err(SpannedError {
353
60
        code: kind,
354
60
        position: Position { line, col },
355
60
    })
356
60
}
357

            
358
#[test]
359
4
fn test_err_wrong_value() {
360
    #[cfg(feature = "std")]
361
    use std::collections::HashMap;
362

            
363
4
    check_from_str_bytes_reader::<f32>("'c'", err(Error::ExpectedFloat, 1, 1));
364
4
    check_from_str_bytes_reader::<String>("'c'", err(Error::ExpectedString, 1, 1));
365
4
    #[cfg(feature = "std")]
366
4
    check_from_str_bytes_reader::<HashMap<u32, u32>>("'c'", err(Error::ExpectedMap, 1, 1));
367
4
    check_from_str_bytes_reader::<[u8; 5]>("'c'", err(Error::ExpectedStructLike, 1, 1));
368
4
    check_from_str_bytes_reader::<Vec<u32>>("'c'", err(Error::ExpectedArray, 1, 1));
369
4
    check_from_str_bytes_reader::<MyEnum>("'c'", err(Error::ExpectedIdentifier, 1, 1));
370
4
    check_from_str_bytes_reader::<MyStruct>(
371
4
        "'c'",
372
4
        err(Error::ExpectedNamedStructLike("MyStruct"), 1, 1),
373
4
    );
374
4
    check_from_str_bytes_reader::<MyStruct>(
375
4
        "NotMyStruct(x: 4, y: 2)",
376
4
        err(
377
4
            Error::ExpectedDifferentStructName {
378
4
                expected: "MyStruct",
379
4
                found: String::from("NotMyStruct"),
380
4
            },
381
4
            1,
382
4
            12,
383
4
        ),
384
4
    );
385
4
    check_from_str_bytes_reader::<(u8, bool)>("'c'", err(Error::ExpectedStructLike, 1, 1));
386
4
    check_from_str_bytes_reader::<bool>("notabool", err(Error::ExpectedBoolean, 1, 1));
387
4

            
388
4
    check_from_str_bytes_reader::<MyStruct>(
389
4
        "MyStruct(\n    x: true)",
390
4
        err(Error::ExpectedFloat, 2, 8),
391
4
    );
392
4
    check_from_str_bytes_reader::<MyStruct>(
393
4
        "MyStruct(\n    x: 3.5, \n    y:)",
394
4
        err(Error::ExpectedFloat, 3, 7),
395
4
    );
396
4
}
397

            
398
#[test]
399
4
fn test_perm_ws() {
400
4
    check_from_str_bytes_reader(
401
4
        "\nMyStruct  \t ( \n x   : 3.5 , \t y\n: 4.5 \n ) \t\n",
402
4
        Ok(MyStruct { x: 3.5, y: 4.5 }),
403
4
    );
404
4
}
405

            
406
#[test]
407
4
fn untagged() {
408
    #[derive(Deserialize, Debug, PartialEq)]
409
    #[serde(untagged)]
410
    enum Untagged {
411
        U8(u8),
412
        Bool(bool),
413
        Value(crate::Value),
414
    }
415

            
416
4
    check_from_str_bytes_reader("true", Ok(Untagged::Bool(true)));
417
4
    check_from_str_bytes_reader("8", Ok(Untagged::U8(8)));
418
4

            
419
4
    // Check for a failure in Deserializer::check_struct_type
420
4
    // - untagged enum and a leading identifier trigger the serde content enum path
421
4
    // - serde content uses deserialize_any, which retriggers the struct type check
422
4
    // - struct type check inside a serde content performs a full newtype check
423
4
    // - newtype check fails on the unclosed struct
424
4
    check_from_str_bytes_reader::<Untagged>(
425
4
        "Value(()",
426
4
        Err(crate::error::SpannedError {
427
4
            code: crate::Error::Eof,
428
4
            position: crate::error::Position { line: 1, col: 9 },
429
4
        }),
430
4
    );
431
4
}
432

            
433
#[test]
434
4
fn rename() {
435
    #[derive(Deserialize, Debug, PartialEq)]
436
    enum Foo {
437
        #[serde(rename = "2d")]
438
        D2,
439
        #[serde(rename = "triangle-list")]
440
        TriangleList,
441
    }
442

            
443
4
    check_from_str_bytes_reader("r#2d", Ok(Foo::D2));
444
4
    check_from_str_bytes_reader("r#triangle-list", Ok(Foo::TriangleList));
445
4
}
446

            
447
#[test]
448
4
fn forgot_apostrophes() {
449
4
    check_from_str_bytes_reader::<(i32, String)>(
450
4
        "(4, \"Hello)",
451
4
        Err(SpannedError {
452
4
            code: Error::ExpectedStringEnd,
453
4
            position: Position { line: 1, col: 6 },
454
4
        }),
455
4
    );
456
4
}
457

            
458
#[test]
459
4
fn expected_attribute() {
460
4
    check_from_str_bytes_reader::<String>("#\"Hello\"", err(Error::ExpectedAttribute, 1, 2));
461
4
}
462

            
463
#[test]
464
4
fn expected_attribute_end() {
465
4
    check_from_str_bytes_reader::<String>(
466
4
        "#![enable(unwrap_newtypes) \"Hello\"",
467
4
        err(Error::ExpectedAttributeEnd, 1, 28),
468
4
    );
469
4
}
470

            
471
#[test]
472
4
fn invalid_attribute() {
473
4
    check_from_str_bytes_reader::<String>(
474
4
        "#![enable(invalid)] \"Hello\"",
475
4
        err(Error::NoSuchExtension("invalid".to_string()), 1, 18),
476
4
    );
477
4
}
478

            
479
#[test]
480
4
fn multiple_attributes() {
481
    #[derive(Debug, Deserialize, PartialEq)]
482
    struct New(String);
483

            
484
4
    check_from_str_bytes_reader(
485
4
        "#![enable(unwrap_newtypes)] #![enable(unwrap_newtypes)] \"Hello\"",
486
4
        Ok(New("Hello".to_owned())),
487
4
    );
488
4
}
489

            
490
#[test]
491
4
fn uglified_attribute() {
492
4
    check_from_str_bytes_reader(
493
4
        "#   !\
494
4
    // We definitely want to add a comment here
495
4
    [\t\tenable( // best style ever
496
4
            unwrap_newtypes  ) ] ()",
497
4
        Ok(()),
498
4
    );
499
4
}
500

            
501
#[test]
502
4
fn implicit_some() {
503
    use serde::de::DeserializeOwned;
504

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

            
508
28
        super::from_str::<Option<T>>(&(enable + s)).unwrap()
509
28
    }
510

            
511
4
    assert_eq!(de("'c'"), Some('c'));
512
4
    assert_eq!(de("5"), Some(5));
513
4
    assert_eq!(de("\"Hello\""), Some("Hello".to_owned()));
514
4
    assert_eq!(de("false"), Some(false));
515
4
    assert_eq!(
516
4
        de("MyStruct(x: .4, y: .5)"),
517
4
        Some(MyStruct { x: 0.4, y: 0.5 })
518
4
    );
519

            
520
4
    assert_eq!(de::<char>("None"), None);
521

            
522
    // Not concise
523
4
    assert_eq!(de::<Option<Option<char>>>("None"), None);
524
4
}
525

            
526
#[test]
527
4
fn ws_tuple_newtype_variant() {
528
4
    check_from_str_bytes_reader("B  ( \n true \n ) ", Ok(MyEnum::B(true)));
529
4
}
530

            
531
#[test]
532
4
fn test_byte_stream() {
533
4
    check_from_str_bytes_reader(
534
4
        "BytesStruct( small:[1, 2], large:b\"\\x01\\x02\\x03\\x04\" )",
535
4
        Ok(BytesStruct {
536
4
            small: vec![1, 2],
537
4
            large: vec![1, 2, 3, 4],
538
4
        }),
539
4
    );
540
4
}
541

            
542
#[test]
543
4
fn test_numbers() {
544
4
    check_from_str_bytes_reader(
545
4
        "[1_234, 12_345, 1_2_3_4_5_6, 1_234_567, 5_55_55_5]",
546
4
        Ok(vec![1234, 12345, 123_456, 1_234_567, 555_555]),
547
4
    );
548
4
}
549

            
550
100
fn check_de_any_number<
551
100
    T: Copy + PartialEq + core::fmt::Debug + Into<Number> + serde::de::DeserializeOwned,
552
100
>(
553
100
    s: &str,
554
100
    cmp: T,
555
100
) {
556
100
    let mut parser = Parser::new(s).unwrap();
557
100
    let number = parser.any_number().unwrap();
558
100

            
559
100
    assert_eq!(number, Number::new(cmp));
560
100
    assert_eq!(
561
100
        Number::new(super::from_str::<T>(s).unwrap()),
562
100
        Number::new(cmp)
563
100
    );
564
100
}
565

            
566
#[test]
567
4
fn test_any_number_precision() {
568
4
    check_de_any_number("1", 1_u8);
569
4
    check_de_any_number("+1", 1_u8);
570
4
    check_de_any_number("-1", -1_i8);
571
4
    check_de_any_number("-1.0", -1.0_f32);
572
4
    check_de_any_number("1.", 1.0_f32);
573
4
    check_de_any_number("-1.", -1.0_f32);
574
4
    check_de_any_number(".3", 0.3_f64);
575
4
    check_de_any_number("-.3", -0.3_f64);
576
4
    check_de_any_number("+.3", 0.3_f64);
577
4
    check_de_any_number("0.3", 0.3_f64);
578
4
    check_de_any_number("NaN", f32::NAN);
579
4
    check_de_any_number("-NaN", -f32::NAN);
580
4
    check_de_any_number("inf", f32::INFINITY);
581
4
    check_de_any_number("-inf", f32::NEG_INFINITY);
582

            
583
    macro_rules! test_min {
584
        ($($ty:ty),*) => {
585
            $(check_de_any_number(&format!("{}", <$ty>::MIN), <$ty>::MIN);)*
586
        };
587
    }
588

            
589
    macro_rules! test_max {
590
        ($($ty:ty),*) => {
591
            $(check_de_any_number(&format!("{}", <$ty>::MAX), <$ty>::MAX);)*
592
        };
593
    }
594

            
595
4
    test_min! { i8, i16, i32, i64, f64 }
596
4
    test_max! { u8, u16, u32, u64, f64 }
597
4
    #[cfg(feature = "integer128")]
598
4
    test_min! { i128 }
599
4
    #[cfg(feature = "integer128")]
600
4
    test_max! { u128 }
601
4
}
602

            
603
#[test]
604
4
fn test_value_special_floats() {
605
    use crate::{from_str, value::Number, Value};
606

            
607
4
    assert_eq!(
608
4
        from_str("NaN"),
609
4
        Ok(Value::Number(Number::F32(f32::NAN.into())))
610
4
    );
611
4
    assert_eq!(
612
4
        from_str("+NaN"),
613
4
        Ok(Value::Number(Number::F32(f32::NAN.into())))
614
4
    );
615
4
    assert_eq!(
616
4
        from_str("-NaN"),
617
4
        Ok(Value::Number(Number::F32((-f32::NAN).into())))
618
4
    );
619

            
620
4
    assert_eq!(
621
4
        from_str("inf"),
622
4
        Ok(Value::Number(Number::F32(f32::INFINITY.into())))
623
4
    );
624
4
    assert_eq!(
625
4
        from_str("+inf"),
626
4
        Ok(Value::Number(Number::F32(f32::INFINITY.into())))
627
4
    );
628
4
    assert_eq!(
629
4
        from_str("-inf"),
630
4
        Ok(Value::Number(Number::F32(f32::NEG_INFINITY.into())))
631
4
    );
632
4
}
633

            
634
#[test]
635
4
fn test_leading_whitespace() {
636
4
    check_from_str_bytes_reader("  +1", Ok(1_u8));
637
4
    check_from_str_bytes_reader("  EmptyStruct1", Ok(EmptyStruct1));
638
4
}
639

            
640
284
fn check_from_str_bytes_reader<T: serde::de::DeserializeOwned + PartialEq + core::fmt::Debug>(
641
284
    ron: &str,
642
284
    check: SpannedResult<T>,
643
284
) {
644
284
    let res_str = super::from_str::<T>(ron);
645
284
    assert_eq!(res_str, check);
646

            
647
284
    let res_bytes = super::from_bytes::<T>(ron.as_bytes());
648
284
    assert_eq!(res_bytes, check);
649

            
650
    #[cfg(feature = "std")]
651
    {
652
284
        let res_reader = super::from_reader::<&[u8], T>(ron.as_bytes());
653
284
        assert_eq!(res_reader, check);
654
    }
655
284
}
656

            
657
#[test]
658
4
fn test_remainder() {
659
4
    let mut deserializer = super::Deserializer::from_str("  42  ").unwrap();
660
4
    assert_eq!(
661
4
        <u8 as serde::Deserialize>::deserialize(&mut deserializer).unwrap(),
662
4
        42
663
4
    );
664
4
    assert_eq!(deserializer.remainder(), "  ");
665
4
    assert_eq!(deserializer.end(), Ok(()));
666

            
667
4
    let mut deserializer = super::Deserializer::from_str("  42 37 ").unwrap();
668
4
    assert_eq!(
669
4
        <u8 as serde::Deserialize>::deserialize(&mut deserializer).unwrap(),
670
4
        42
671
4
    );
672
4
    assert_eq!(deserializer.remainder(), " 37 ");
673
4
    assert_eq!(deserializer.end(), Err(Error::TrailingCharacters));
674
4
}
675

            
676
#[test]
677
4
fn boolean_struct_name() {
678
4
    check_from_str_bytes_reader::<bool>(
679
4
        "true_",
680
4
        Err(SpannedError {
681
4
            code: Error::ExpectedBoolean,
682
4
            position: Position { line: 1, col: 1 },
683
4
        }),
684
4
    );
685
4
    check_from_str_bytes_reader::<bool>(
686
4
        "false_",
687
4
        Err(SpannedError {
688
4
            code: Error::ExpectedBoolean,
689
4
            position: Position { line: 1, col: 1 },
690
4
        }),
691
4
    );
692
4
}