1
#[cfg(feature = "alloc")]
2
use alloc::{
3
    string::{String, ToString},
4
    vec,
5
};
6
use core::fmt::Write;
7
use std::println;
8

            
9
use crate::anystr::AnyStr;
10
use crate::doc::Document;
11
use crate::parser::{ParseConfig, ParseDelegate, Parser};
12
use crate::string::StringContents;
13
use crate::value::ValueParser;
14
use crate::{Error, ErrorKind, JsonNumber, JsonString, JsonStringInfo, Object, Value};
15

            
16
#[track_caller]
17
32
fn test_json_parse(source: &[u8], value: &Value<'_>) {
18
32
    println!("Testing slice {}", std::str::from_utf8(source).unwrap());
19
32

            
20
32
    let parsed_value = Value::from_json_bytes(source).unwrap();
21
32
    assert_eq!(&parsed_value, value);
22

            
23
32
    let doc = Document::from_json_bytes(source).unwrap();
24
32
    assert_eq!(Value::from(doc), parsed_value);
25
32
}
26

            
27
1
#[test]
28
1
fn keywords() {
29
1
    test_json_parse(b"true", &Value::from(true));
30
1
    test_json_parse(b"false", &Value::from(false));
31
1
    test_json_parse(b"null", &Value::Null);
32
1
}
33

            
34
1
#[test]
35
1
fn empty_array() {
36
1
    test_json_parse(b"[]", &Value::Array(vec![]));
37
1
}
38

            
39
1
#[test]
40
1
fn one_element_array() {
41
1
    test_json_parse(b"[true]", &Value::Array(vec![Value::from(true)]));
42
1
}
43

            
44
1
#[test]
45
1
fn two_element_array() {
46
1
    test_json_parse(
47
1
        b"[true,false]",
48
1
        &Value::Array(vec![Value::from(true), Value::from(false)]),
49
1
    );
50
1
}
51

            
52
1
#[test]
53
1
fn spaced_out_array() {
54
1
    test_json_parse(
55
1
        b" [ true , false ] ",
56
1
        &Value::Array(vec![Value::from(true), Value::from(false)]),
57
1
    );
58
1
}
59

            
60
1
#[test]
61
1
fn whitespace() {
62
1
    test_json_parse(b" \t\n\rnull", &Value::Null);
63
1
}
64

            
65
1
#[test]
66
1
fn basic_string() {
67
1
    test_json_parse(
68
1
        br#""hello""#,
69
1
        &Value::from(JsonString {
70
1
            source: StringContents::Json(AnyStr::Borrowed("hello")),
71
1
            info: JsonStringInfo::new(false, 5),
72
1
        }),
73
1
    );
74
1
    test_json_parse(
75
1
        br#""""#,
76
1
        &Value::from(JsonString {
77
1
            source: StringContents::Json(AnyStr::Borrowed("")),
78
1
            info: JsonStringInfo::new(false, 0),
79
1
        }),
80
1
    );
81
1
}
82

            
83
1
#[test]
84
1
fn escapey_string() {
85
1
    test_json_parse(
86
1
        br#""\"\\\/\b\f\n\r\t\u25eF""#,
87
1
        &Value::from(JsonString {
88
1
            source: StringContents::Json(AnyStr::Borrowed(r#"\"\\\/\b\f\n\r\t\u25eF"#)),
89
1
            info: JsonStringInfo::new(true, 11),
90
1
        }),
91
1
    );
92
1
}
93

            
94
1
#[test]
95
1
fn surrogate_pair() {
96
1
    test_json_parse(
97
1
        br#""\ud83d\ude39\ud83d\udc8d""#,
98
1
        &Value::from(JsonString::from_json("\"\u{1f639}\u{1f48d}\"").unwrap()),
99
1
    );
100
1
    assert_eq!(
101
1
        JsonString::from_json(r#""\ud83d\ude39\ud83d\udc8d""#,).unwrap(),
102
1
        "\u{1f639}\u{1f48d}"
103
1
    );
104
1
}
105

            
106
1
#[test]
107
1
fn empty_object() {
108
1
    test_json_parse(b"{}", &Value::Object(Object::new()));
109
1
}
110

            
111
1
#[test]
112
1
fn one_mapping() {
113
1
    test_json_parse(
114
1
        br#"{"hello":true}"#,
115
1
        &Value::Object(Object::from_iter([(
116
1
            JsonString {
117
1
                source: StringContents::Json(AnyStr::Borrowed("hello")),
118
1
                info: JsonStringInfo::new(false, 5),
119
1
            },
120
1
            Value::from(true),
121
1
        )])),
122
1
    );
123
1
}
124

            
125
1
#[test]
126
1
fn two_mappings() {
127
1
    test_json_parse(
128
1
        br#"{"hello":true,"world":null}"#,
129
1
        &Value::Object(Object::from_iter([
130
1
            (
131
1
                JsonString {
132
1
                    source: StringContents::Json(AnyStr::Borrowed("hello")),
133
1
                    info: JsonStringInfo::new(false, 5),
134
1
                },
135
1
                Value::from(true),
136
1
            ),
137
1
            (
138
1
                JsonString {
139
1
                    source: StringContents::Json(AnyStr::Borrowed("world")),
140
1
                    info: JsonStringInfo::new(false, 5),
141
1
                },
142
1
                Value::Null,
143
1
            ),
144
1
        ])),
145
1
    );
146
1
}
147

            
148
1
#[test]
149
1
fn spaced_out_object() {
150
1
    test_json_parse(
151
1
        br#" { "hello" : true , "world" : null } "#,
152
1
        &Value::Object(Object::from_iter([
153
1
            (
154
1
                JsonString::from_json("\"hello\"").unwrap(),
155
1
                Value::from(true),
156
1
            ),
157
1
            (JsonString::from_json("\"world\"").unwrap(), Value::Null),
158
1
        ])),
159
1
    );
160
1
}
161

            
162
1
#[test]
163
1
fn numbers() {
164
11
    for b in b'0'..=b'9' {
165
10
        test_json_parse(
166
10
            &[b],
167
10
            &Value::Number(JsonNumber {
168
10
                source: AnyStr::Borrowed(std::str::from_utf8(&[b]).unwrap()),
169
10
            }),
170
10
        );
171
10
    }
172

            
173
1
    test_json_parse(
174
1
        b"-1",
175
1
        &Value::Number(JsonNumber {
176
1
            source: AnyStr::Borrowed("-1"),
177
1
        }),
178
1
    );
179
1

            
180
1
    test_json_parse(
181
1
        b"-1.0",
182
1
        &Value::Number(JsonNumber {
183
1
            source: AnyStr::Borrowed("-1.0"),
184
1
        }),
185
1
    );
186
1

            
187
1
    test_json_parse(
188
1
        b"-1.0e1",
189
1
        &Value::Number(JsonNumber {
190
1
            source: AnyStr::Borrowed("-1.0e1"),
191
1
        }),
192
1
    );
193
1

            
194
1
    test_json_parse(
195
1
        b"-1.0E-1",
196
1
        &Value::Number(JsonNumber {
197
1
            source: AnyStr::Borrowed("-1.0E-1"),
198
1
        }),
199
1
    );
200
1
}
201

            
202
1
#[test]
203
1
fn object_of_everything() {
204
1
    test_json_parse(
205
1
        br#"{"a":1,"b":true,"c":"hello","d":[],"e":{}}"#,
206
1
        &Value::Object(Object::from_iter([
207
1
            (
208
1
                JsonString::from_json(r#""a""#).unwrap(),
209
1
                Value::Number(JsonNumber {
210
1
                    source: AnyStr::Borrowed("1"),
211
1
                }),
212
1
            ),
213
1
            (JsonString::from_json(r#""b""#).unwrap(), Value::from(true)),
214
1
            (
215
1
                JsonString::from_json(r#""c""#).unwrap(),
216
1
                Value::from(JsonString::from_json(r#""hello""#).unwrap()),
217
1
            ),
218
1
            (
219
1
                JsonString::from_json(r#""d""#).unwrap(),
220
1
                Value::Array(vec![]),
221
1
            ),
222
1
            (
223
1
                JsonString::from_json(r#""e""#).unwrap(),
224
1
                Value::Object(Object::new()),
225
1
            ),
226
1
        ])),
227
1
    );
228
1
}
229

            
230
1
#[test]
231
1
fn array_of_everything() {
232
1
    test_json_parse(
233
1
        br#"[1,true,"hello",[],{}]"#,
234
1
        &Value::Array(vec![
235
1
            Value::Number(JsonNumber {
236
1
                source: AnyStr::Borrowed("1"),
237
1
            }),
238
1
            Value::from(true),
239
1
            Value::from(JsonString::from_json(r#""hello""#).unwrap()),
240
1
            Value::Array(vec![]),
241
1
            Value::Object(Object::new()),
242
1
        ]),
243
1
    );
244
1
}
245

            
246
#[track_caller]
247
33
fn expect_json_error(json: &str) -> Error {
248
33
    println!("Parsing {json}");
249
33
    let err = Value::from_json(json).expect_err("parsing did not error");
250
33
    println!("> {err:?}");
251
33
    err
252
33
}
253

            
254
macro_rules! assert_json_error_kind_matches {
255
    ($json:expr, $offset:expr, $kind:expr) => {{
256
        let err = expect_json_error($json);
257
        assert_eq!(err.kind(), &$kind);
258
        assert_eq!(err.offset(), $offset);
259
    }};
260
}
261

            
262
1
#[test]
263
1
fn object_errors() {
264
1
    assert_json_error_kind_matches!("{1:true}", 1, ErrorKind::ObjectKeysMustBeStrings);
265
1
    assert_json_error_kind_matches!(r#"{"a": true,}"#, 11, ErrorKind::IllegalTrailingComma);
266
1
    assert_json_error_kind_matches!(r#"{"a": true,:"#, 11, ErrorKind::ExpectedObjectKey);
267
1
    assert_json_error_kind_matches!(r#"{"a"}"#, 4, ErrorKind::ExpectedColon);
268
1
    assert_json_error_kind_matches!(r#"{"a""#, 4, ErrorKind::ExpectedColon);
269
1
    assert_json_error_kind_matches!(r#"{"a":}"#, 5, ErrorKind::Unexpected(b'}'));
270
1
    assert_json_error_kind_matches!(r#"{"a":1]"#, 6, ErrorKind::ExpectedCommaOrEndOfObject);
271
1
    assert_json_error_kind_matches!(r#"{"a": true,"#, 11, ErrorKind::UnclosedObject);
272
1
}
273

            
274
1
#[test]
275
1
fn array_errors() {
276
1
    assert_json_error_kind_matches!("[1,]", 3, ErrorKind::IllegalTrailingComma);
277

            
278
1
    assert_json_error_kind_matches!("[1}", 2, ErrorKind::ExpectedCommaOrEndOfArray);
279

            
280
1
    assert_json_error_kind_matches!("[1,,}", 3, ErrorKind::Unexpected(b','));
281

            
282
1
    assert_json_error_kind_matches!("[1,", 3, ErrorKind::UnclosedArray);
283

            
284
1
    assert_json_error_kind_matches!("[", 1, ErrorKind::UnclosedArray);
285
1
}
286

            
287
1
#[test]
288
1
fn keyword_errors() {
289
1
    assert_json_error_kind_matches!("tru ", 3, ErrorKind::Unexpected(b' '));
290
1
    assert_json_error_kind_matches!("tru", 3, ErrorKind::UnexpectedEof);
291
1
}
292

            
293
1
#[test]
294
1
fn json_errors() {
295
1
    assert_json_error_kind_matches!("true true", 5, ErrorKind::TrailingNonWhitespace);
296

            
297
1
    assert_json_error_kind_matches!(",", 0, ErrorKind::Unexpected(b','));
298

            
299
1
    assert_json_error_kind_matches!("#", 0, ErrorKind::Unexpected(b'#'));
300

            
301
1
    assert_json_error_kind_matches!("", 0, ErrorKind::UnexpectedEof);
302
1
}
303

            
304
1
#[test]
305
1
fn string_errors() {
306
1
    assert_json_error_kind_matches!(r#"""#, 1, ErrorKind::UnclosedString);
307

            
308
1
    assert_json_error_kind_matches!("\"\0\"", 1, ErrorKind::Unexpected(b'\0'));
309

            
310
1
    assert_json_error_kind_matches!(r#""\?"#, 2, ErrorKind::InvalidEscape);
311

            
312
1
    assert_json_error_kind_matches!(r#""\udddd "#, 2, ErrorKind::Utf8);
313
1
    assert_json_error_kind_matches!(r#""\udda1 "#, 2, ErrorKind::Utf8);
314

            
315
1
    assert_json_error_kind_matches!(r#""\uG"#, 3, ErrorKind::InvalidHexadecimal);
316

            
317
1
    println!("Parsing invalid unicode");
318
1
    let err = Value::from_json_bytes(b"\"\xdd\xdd\"").expect_err("parsing did not error");
319
1
    println!("> {err:?}");
320
1
    assert!(matches!(err.kind(), ErrorKind::Utf8));
321
1
}
322

            
323
1
#[test]
324
1
fn number_errors() {
325
1
    assert_json_error_kind_matches!("- ", 1, ErrorKind::ExpectedDigit);
326

            
327
1
    assert_json_error_kind_matches!("1. ", 2, ErrorKind::ExpectedDecimalDigit);
328

            
329
1
    assert_json_error_kind_matches!("1.0E ", 4, ErrorKind::ExpectedExponent);
330

            
331
1
    assert_json_error_kind_matches!("1.0E- ", 5, ErrorKind::ExpectedExponent);
332

            
333
    // Same battery of tests but with an eof instead
334
1
    assert_json_error_kind_matches!("-", 1, ErrorKind::ExpectedDigit);
335

            
336
1
    assert_json_error_kind_matches!("1.", 2, ErrorKind::ExpectedDecimalDigit);
337

            
338
1
    assert_json_error_kind_matches!("1.0E", 4, ErrorKind::ExpectedExponent);
339

            
340
1
    assert_json_error_kind_matches!("1.0E-", 5, ErrorKind::ExpectedExponent);
341
1
}
342

            
343
3
fn test_roundtrip_encoding(source: &str) {
344
3
    println!("Testing {source}");
345
3
    let value = Value::from_json(source).unwrap();
346
3
    assert_eq!(value.to_json(), source);
347
3
}
348

            
349
1
fn test_roundtrip_encoding_pretty_custom(source: &str, indentation: &str, line_ending: &str) {
350
1
    println!("Testing {source}");
351
1
    let value = Value::from_json(source).unwrap();
352
1
    assert_eq!(
353
1
        value.to_json_pretty_custom(indentation, line_ending),
354
1
        source
355
1
    );
356
1
}
357

            
358
2
fn test_roundtrip_encoding_pretty(source: &str) {
359
2
    println!("Testing {source}");
360
2
    let value = Value::from_json(source).unwrap();
361
2
    assert_eq!(value.to_json_pretty(), source);
362
2
}
363

            
364
1
#[test]
365
1
fn json_formatting() {
366
1
    test_roundtrip_encoding(r#"[1,true,"hello",[],{}]"#);
367
1
    test_roundtrip_encoding(r#"{"a":1,"b":true,"c":"hello","d":[],"e":{}}"#);
368
1
    test_roundtrip_encoding_pretty("[\n  1,\n  true,\n  \"hello\",\n  [],\n  {}\n]");
369
1
    test_roundtrip_encoding_pretty(
370
1
        "{\n  \"a\": 1,\n  \"b\": true,\n  \"c\": \"hello\",\n  \"d\": [],\n  \"e\": {}\n}",
371
1
    );
372
1
    test_roundtrip_encoding_pretty_custom(
373
1
        "{\r\t\"a\": 1,\r\t\"b\": true,\r\t\"c\": \"hello\",\r\t\"d\": [],\r\t\"e\": {}\r}",
374
1
        "\t",
375
1
        "\r",
376
1
    );
377
1
    test_roundtrip_encoding(r#""\u0000""#);
378
1
}
379

            
380
1
#[test]
381
1
fn value_display() {
382
1
    let value = Value::from_json(r#"{"a":1,"b":true,"c":"hello","d":[],"e":{}}"#).unwrap();
383
1
    assert_eq!(
384
1
        value.to_string(),
385
1
        r#"{"a":1,"b":true,"c":"hello","d":[],"e":{}}"#
386
1
    );
387
1
    let mut pretty = String::new();
388
1
    write!(&mut pretty, "{value:#}").unwrap();
389
1
    assert_eq!(
390
1
        pretty,
391
1
        "{\n  \"a\": 1,\n  \"b\": true,\n  \"c\": \"hello\",\n  \"d\": [],\n  \"e\": {}\n}"
392
1
    );
393
1
}
394

            
395
struct ErroringDelegate {
396
    parser: ValueParser,
397
    error_on: ErrorOn,
398
}
399
impl ErroringDelegate {
400
15
    pub fn new(error_on: ErrorOn) -> Self {
401
15
        Self {
402
15
            error_on,
403
15
            parser: ValueParser,
404
15
        }
405
15
    }
406
}
407

            
408
16
#[derive(Debug, Eq, PartialEq)]
409
enum ErrorOn {
410
    None,
411
    Null,
412
    Boolean(bool),
413
    Number(&'static str),
414
    String,
415
    BeginObject,
416
    ObjectKey,
417
    ObjectValue,
418
    EndObject,
419
    BeginArray,
420
    ArrayValue,
421
    EndArray,
422
}
423

            
424
14
#[derive(Eq, PartialEq, Debug)]
425
struct MyError;
426

            
427
impl<'a> ParseDelegate<'a> for ErroringDelegate {
428
    type Array = <ValueParser as ParseDelegate<'a>>::Array;
429
    type Error = MyError;
430
    type Key = JsonString<'a>;
431
    type Object = Object<'a>;
432
    type Value = Value<'a>;
433

            
434
9
    fn null(&mut self) -> Result<Self::Value, Self::Error> {
435
9
        if matches!(self.error_on, ErrorOn::Null) {
436
1
            Err(MyError)
437
        } else {
438
8
            Ok(self.parser.null().unwrap())
439
        }
440
9
    }
441

            
442
16
    fn boolean(&mut self, value: bool) -> Result<Self::Value, Self::Error> {
443
16
        if self.error_on == ErrorOn::Boolean(value) {
444
2
            Err(MyError)
445
        } else {
446
14
            Ok(self.parser.boolean(value).unwrap())
447
        }
448
16
    }
449

            
450
    fn number(&mut self, value: JsonNumber<'a>) -> Result<Self::Value, Self::Error> {
451
6
        match &self.error_on {
452
6
            ErrorOn::Number(number) if value.source() == *number => Err(MyError),
453
23
            _ => Ok(self.parser.number(value).unwrap()),
454
        }
455
26
    }
456

            
457
12
    fn string(&mut self, value: JsonString<'a>) -> Result<Self::Value, Self::Error> {
458
12
        if matches!(self.error_on, ErrorOn::String) {
459
1
            Err(MyError)
460
        } else {
461
11
            Ok(self.parser.string(value).unwrap())
462
        }
463
12
    }
464

            
465
17
    fn begin_object(&mut self) -> Result<Self::Object, Self::Error> {
466
17
        if matches!(self.error_on, ErrorOn::BeginObject) {
467
1
            Err(MyError)
468
        } else {
469
16
            Ok(self.parser.begin_object().unwrap())
470
        }
471
17
    }
472

            
473
49
    fn object_key(
474
49
        &mut self,
475
49
        object: &mut Self::Object,
476
49
        key: JsonString<'a>,
477
49
    ) -> Result<Self::Key, Self::Error> {
478
49
        if matches!(self.error_on, ErrorOn::ObjectKey) {
479
1
            Err(MyError)
480
        } else {
481
48
            Ok(self.parser.object_key(object, key).unwrap())
482
        }
483
49
    }
484

            
485
37
    fn object_value(
486
37
        &mut self,
487
37
        object: &mut Self::Object,
488
37
        key: Self::Key,
489
37
        value: Self::Value,
490
37
    ) -> Result<(), Self::Error> {
491
37
        if matches!(self.error_on, ErrorOn::ObjectValue) {
492
1
            Err(MyError)
493
        } else {
494
36
            self.parser.object_value(object, key, value).unwrap();
495
36
            Ok(())
496
        }
497
37
    }
498

            
499
2
    fn object_is_empty(&self, object: &Self::Object) -> bool {
500
2
        self.parser.object_is_empty(object)
501
2
    }
502

            
503
3
    fn end_object(&mut self, object: Self::Object) -> Result<Self::Value, Self::Error> {
504
3
        if matches!(self.error_on, ErrorOn::EndObject) {
505
1
            Err(MyError)
506
        } else {
507
2
            Ok(self.parser.end_object(object).unwrap())
508
        }
509
3
    }
510

            
511
13
    fn begin_array(&mut self) -> Result<Self::Array, Self::Error> {
512
13
        if matches!(self.error_on, ErrorOn::BeginArray) {
513
1
            Err(MyError)
514
        } else {
515
12
            Ok(self.parser.begin_array().unwrap())
516
        }
517
13
    }
518

            
519
24
    fn array_value(
520
24
        &mut self,
521
24
        array: &mut Self::Array,
522
24
        value: Self::Value,
523
24
    ) -> Result<(), Self::Error> {
524
24
        if matches!(self.error_on, ErrorOn::ArrayValue) {
525
1
            Err(MyError)
526
        } else {
527
23
            self.parser.array_value(array, value).unwrap();
528
23
            Ok(())
529
        }
530
24
    }
531

            
532
3
    fn array_is_empty(&self, array: &Self::Array) -> bool {
533
3
        self.parser.array_is_empty(array)
534
3
    }
535

            
536
5
    fn end_array(&mut self, array: Self::Array) -> Result<Self::Value, Self::Error> {
537
5
        if matches!(self.error_on, ErrorOn::EndArray) {
538
1
            Err(MyError)
539
        } else {
540
4
            Ok(self.parser.end_array(array).unwrap())
541
        }
542
5
    }
543

            
544
1
    fn kind_of(&self, value: &Self::Value) -> crate::parser::JsonKind {
545
1
        self.parser.kind_of(value)
546
1
    }
547
}
548

            
549
1
#[test]
550
1
fn parse_delegate_error() {
551
1
    let payload =
552
1
        br#"{"a":1,"b":true,"c":"hello","d":[null, -1, 0, false, []],"e":{},"f":"error"}"#;
553
1
    Parser::parse_json_bytes_with_config(
554
1
        payload,
555
1
        ParseConfig::strict(),
556
1
        ErroringDelegate::new(ErrorOn::None),
557
1
    )
558
1
    .expect("no errors");
559

            
560
14
    for error_on in [
561
1
        ErrorOn::Null,
562
1
        ErrorOn::Boolean(false),
563
1
        ErrorOn::Boolean(false),
564
1
        ErrorOn::Number("1"),
565
1
        ErrorOn::Number("-1"),
566
1
        ErrorOn::Number("0"),
567
1
        ErrorOn::String,
568
1
        ErrorOn::BeginObject,
569
1
        ErrorOn::ObjectKey,
570
1
        ErrorOn::ObjectValue,
571
1
        ErrorOn::EndObject,
572
1
        ErrorOn::BeginArray,
573
1
        ErrorOn::ArrayValue,
574
1
        ErrorOn::EndArray,
575
    ] {
576
14
        println!("Trying to error on {error_on:?}");
577
14
        let err = Parser::parse_json_bytes(payload, ErroringDelegate::new(error_on))
578
14
            .expect_err("expecting delegate error");
579
14

            
580
14
        assert_eq!(err.kind(), &ErrorKind::ErrorFromDelegate(MyError));
581
    }
582
1
}
583

            
584
1
#[test]
585
1
fn illegal_types_at_root() {
586
4
    fn test_payload(json: &str) {
587
4
        assert_eq!(
588
4
            Document::from_json_with_config(json, ParseConfig::strict())
589
4
                .unwrap_err()
590
4
                .kind,
591
4
            ErrorKind::PayloadsShouldBeObjectOrArray
592
4
        );
593
4
        assert_eq!(
594
4
            Value::from_json_with_config(json, ParseConfig::strict())
595
4
                .unwrap_err()
596
4
                .kind,
597
4
            ErrorKind::PayloadsShouldBeObjectOrArray
598
4
        );
599
4
    }
600
1

            
601
1
    test_payload("null");
602
1
    test_payload("true");
603
1
    test_payload("1");
604
1
    test_payload("\"\"");
605
1
}