1
/*
2
 * Hurl (https://hurl.dev)
3
 * Copyright (C) 2026 Orange
4
 *
5
 * Licensed under the Apache License, Version 2.0 (the "License");
6
 * you may not use this file except in compliance with the License.
7
 * You may obtain a copy of the License at
8
 *
9
 *          http://www.apache.org/licenses/LICENSE-2.0
10
 *
11
 * Unless required by applicable law or agreed to in writing, software
12
 * distributed under the License is distributed on an "AS IS" BASIS,
13
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
 * See the License for the specific language governing permissions and
15
 * limitations under the License.
16
 *
17
 */
18
use crate::ast::{
19
    JsonListElement, JsonObjectElement, JsonValue, JsonValueKind, SourceInfo, Template,
20
};
21
use crate::combinator::{ParseError as ParseErrorTrait, choice, non_recover};
22
use crate::reader::{Pos, Reader};
23

            
24
use super::error::{JsonErrorVariant, ParseError, ParseErrorKind};
25
use super::primitives::{boolean, hex_digit, literal, try_literal};
26
use super::template::{EncodedString, templatize};
27
use super::{ParseResult, placeholder};
28

            
29
const MAX_NESTING_DEPTH: usize = 128;
30

            
31
/// Parse a JSON value from the reader.
32
24248
pub fn parse(reader: &mut Reader) -> ParseResult<JsonValue> {
33
24248
    parse_at_depth(reader, 0)
34
}
35

            
36
/// Parse a JSON value from the reader, considering the current nesting depth.
37
28820
fn parse_at_depth(reader: &mut Reader, depth: usize) -> ParseResult<JsonValue> {
38
28820
    let start = reader.cursor().pos;
39
28820
    let kind = parse_kind_at_depth(reader, depth)?;
40
4452
    Ok(JsonValue::new(
41
4452
        SourceInfo::new(start, reader.cursor().pos),
42
4452
        kind,
43
4452
    ))
44
}
45

            
46
28820
fn parse_kind_at_depth(reader: &mut Reader, depth: usize) -> ParseResult<JsonValueKind> {
47
28820
    let parsers = [
48
28820
        null_value_kind,
49
28820
        boolean_value_kind,
50
28820
        string_value_kind,
51
28820
        number_value_kind,
52
28820
        expression_value_kind,
53
28820
    ];
54
28820
    let start = reader.cursor();
55
28820
    match choice(&parsers, reader) {
56
25732
        Err(error) if error.recoverable => reader.seek(start),
57
3088
        result => return result,
58
    }
59

            
60
25732
    let start = reader.cursor();
61
25732
    match list_value_kind(reader, depth) {
62
24724
        Err(error) if error.recoverable => reader.seek(start),
63
1008
        result => return result,
64
    }
65
24724
    object_value_kind(reader, depth)
66
}
67

            
68
/// Helper for parse, but already knowing that we are inside a JSON body.
69
4572
fn parse_in_json(reader: &mut Reader, depth: usize) -> ParseResult<JsonValue> {
70
4572
    if let Some(c) = reader.peek()
71
4572
        && c == ','
72
    {
73
        let kind = ParseErrorKind::Json(JsonErrorVariant::EmptyElement);
74
        return Err(ParseError::new(reader.cursor().pos, false, kind));
75
    }
76
4572
    match parse_at_depth(reader, depth) {
77
4028
        Ok(r) => Ok(r),
78
        // The only error that is recoverable is caused by reaching object_value try_literal('{'),
79
        // but this is not recoverable in this case, because we already know that we are in a JSON
80
        // body. So, we change the error to CannotResolve for the object found.
81
544
        Err(e) => match e {
82
            ParseError {
83
                recoverable: true, ..
84
            } => {
85
12
                let kind = ParseErrorKind::Json(JsonErrorVariant::ExpectingElement);
86
12
                Err(ParseError::new(e.pos, false, kind))
87
            }
88
532
            _ => Err(ParseError::new(e.pos, false, e.kind)),
89
        },
90
    }
91
}
92

            
93
16
pub fn null_value(reader: &mut Reader) -> ParseResult<JsonValue> {
94
16
    let start = reader.cursor().pos;
95
16
    let kind = null_value_kind(reader)?;
96
4
    Ok(JsonValue::new(
97
4
        SourceInfo::new(start, reader.cursor().pos),
98
4
        kind,
99
4
    ))
100
}
101

            
102
28836
fn null_value_kind(reader: &mut Reader) -> ParseResult<JsonValueKind> {
103
28836
    try_literal("null", reader)?;
104
40
    Ok(JsonValueKind::Null)
105
}
106

            
107
20
pub fn boolean_value(reader: &mut Reader) -> ParseResult<JsonValue> {
108
20
    let start = reader.cursor().pos;
109
20
    let kind = boolean_value_kind(reader)?;
110
4
    Ok(JsonValue::new(
111
4
        SourceInfo::new(start, reader.cursor().pos),
112
4
        kind,
113
4
    ))
114
}
115

            
116
28804
fn boolean_value_kind(reader: &mut Reader) -> ParseResult<JsonValueKind> {
117
28804
    let value = boolean(reader)?;
118
136
    Ok(JsonValueKind::Boolean(value))
119
}
120

            
121
28652
fn string_value_kind(reader: &mut Reader) -> ParseResult<JsonValueKind> {
122
28652
    let template = string_template(reader)?;
123
1720
    Ok(JsonValueKind::String(template))
124
}
125

            
126
31336
fn string_template(reader: &mut Reader) -> ParseResult<Template> {
127
31336
    try_literal("\"", reader)?;
128
4412
    let delimiter = Some('"');
129
4412
    let mut chars = vec![];
130
4412
    let start = reader.cursor();
131
    loop {
132
41000
        if reader.peek() == Some('"') || reader.is_eof() {
133
4404
            break;
134
        }
135
36596
        let char = any_char(reader)?;
136
36588
        chars.push(char);
137
    }
138
4404
    let end = reader.cursor();
139

            
140
4404
    let encoded_string = EncodedString {
141
4404
        source_info: SourceInfo::new(start.pos, end.pos),
142
4404
        chars,
143
4404
    };
144
4404
    literal("\"", reader)?;
145
4404
    let elements = templatize(encoded_string)?;
146

            
147
4404
    let template = Template::new(delimiter, elements, SourceInfo::new(start.pos, end.pos));
148
4404
    Ok(template)
149
}
150

            
151
36596
fn any_char(reader: &mut Reader) -> ParseResult<(char, String, Pos)> {
152
36596
    let start = reader.cursor();
153
36596
    match escape_char(reader) {
154
312
        Ok(c) => Ok((c, reader.read_from(start.index), start.pos)),
155
36284
        Err(e) => {
156
36284
            if e.recoverable {
157
36276
                reader.seek(start);
158
36276
                match reader.read() {
159
                    None => {
160
                        let kind = ParseErrorKind::Expecting {
161
                            value: "char".to_string(),
162
                        };
163
                        Err(ParseError::new(start.pos, true, kind))
164
                    }
165
36276
                    Some(c) => {
166
36276
                        if ['\\', '\x08', '\n', '\x0c', '\r', '\t'].contains(&c) {
167
                            let kind = ParseErrorKind::Expecting {
168
                                value: "char".to_string(),
169
                            };
170
                            Err(ParseError::new(start.pos, true, kind))
171
                        } else {
172
36276
                            Ok((c, reader.read_from(start.index), start.pos))
173
                        }
174
                    }
175
                }
176
            } else {
177
8
                Err(e)
178
            }
179
        }
180
    }
181
}
182

            
183
36596
fn escape_char(reader: &mut Reader) -> ParseResult<char> {
184
36596
    try_literal("\\", reader)?;
185
320
    let start = reader.cursor();
186
320
    match reader.read() {
187
164
        Some('"') => Ok('"'),
188
8
        Some('\\') => Ok('\\'),
189
        Some('/') => Ok('/'),
190
        Some('b') => Ok('\x08'),
191
132
        Some('n') => Ok('\n'),
192
        Some('f') => Ok('\x0c'),
193
        Some('r') => Ok('\r'),
194
4
        Some('t') => Ok('\t'),
195
12
        Some('u') => unicode(reader),
196
        _ => Err(ParseError::new(
197
            start.pos,
198
            false,
199
            ParseErrorKind::EscapeChar,
200
        )),
201
    }
202
}
203

            
204
12
fn unicode(reader: &mut Reader) -> ParseResult<char> {
205
12
    let start = reader.cursor();
206
12
    let cp1 = hex_value(reader)?;
207
8
    let cp = if is_surrogate(cp1) {
208
8
        literal("\\u", reader)?;
209
8
        let start = reader.cursor();
210
8
        let cp2 = hex_value(reader)?;
211
8
        match cp_surrogate_pair(cp1, cp2) {
212
4
            None => return Err(ParseError::new(start.pos, false, ParseErrorKind::Unicode)),
213
4
            Some(cp) => cp,
214
        }
215
    } else {
216
        cp1
217
    };
218
4
    let c = match char::from_u32(cp) {
219
        None => return Err(ParseError::new(start.pos, false, ParseErrorKind::Unicode)),
220
4
        Some(c) => c,
221
    };
222
4
    Ok(c)
223
}
224

            
225
// 0xd800-0xdc00 encodes the high 10 bits of a pair.
226
// 0xdc00-0xe000 encodes the low 10 bits of a pair.
227
// the value is those 20 bits plus 0x10000.
228
const SURR1: u32 = 0xd800;
229
const SURR2: u32 = 0xdc00;
230
const SURR3: u32 = 0xe000;
231
const SURR_SELF: u32 = 0x10000;
232

            
233
/// Returns whether the specified Unicode code point can appear in a surrogate pair.
234
8
fn is_surrogate(cp: u32) -> bool {
235
8
    (SURR1..SURR3).contains(&cp)
236
}
237

            
238
8
fn cp_surrogate_pair(cp1: u32, cp2: u32) -> Option<u32> {
239
8
    if (SURR1..SURR2).contains(&cp1) && (SURR2..SURR3).contains(&cp2) {
240
4
        Some(((cp1 - SURR1) << 10) | ((cp2 - SURR2) + SURR_SELF))
241
    } else {
242
4
        None
243
    }
244
}
245

            
246
20
fn hex_value(reader: &mut Reader) -> ParseResult<u32> {
247
20
    let digit1 = non_recover(hex_digit, reader)?;
248
20
    let digit2 = non_recover(hex_digit, reader)?;
249
20
    let digit3 = non_recover(hex_digit, reader)?;
250
20
    let digit4 = non_recover(hex_digit, reader)?;
251
16
    let value = digit1 * (16 * 16 * 16) + digit2 * (16 * 16) + digit3 * 16 + digit4;
252
16
    Ok(value)
253
}
254

            
255
32
pub fn number_value(reader: &mut Reader) -> ParseResult<JsonValue> {
256
32
    let start = reader.cursor().pos;
257
32
    let kind = number_value_kind(reader)?;
258
12
    Ok(JsonValue::new(
259
12
        SourceInfo::new(start, reader.cursor().pos),
260
12
        kind,
261
12
    ))
262
}
263

            
264
26956
fn number_value_kind(reader: &mut Reader) -> ParseResult<JsonValueKind> {
265
26956
    let sign = match try_literal("-", reader) {
266
26920
        Err(_) => String::new(),
267
36
        Ok(_) => "-".to_string(),
268
    };
269
26956
    let int = integer(reader)?;
270
1156
    let frac = fraction(reader)?;
271
1156
    let exp = exponent(reader)?;
272
1156
    Ok(JsonValueKind::Number(format!("{sign}{int}{frac}{exp}")))
273
}
274

            
275
26956
fn integer(reader: &mut Reader) -> ParseResult<String> {
276
26956
    let start = reader.cursor();
277
26956
    match try_literal("0", reader) {
278
        Err(_) => {
279
26748
            let digits = reader.read_while(|c| c.is_ascii_digit());
280
26748
            if digits.is_empty() {
281
25800
                let kind = ParseErrorKind::Expecting {
282
25800
                    value: "number".to_string(),
283
25800
                };
284
25800
                Err(ParseError::new(start.pos, true, kind))
285
            } else {
286
948
                Ok(digits)
287
            }
288
        }
289
208
        Ok(_) => Ok("0".to_string()),
290
    }
291
}
292

            
293
1156
fn fraction(reader: &mut Reader) -> ParseResult<String> {
294
1156
    match try_literal(".", reader) {
295
        Ok(_) => {
296
3576
            let digits = reader.read_while(|c| c.is_ascii_digit());
297
596
            if digits.is_empty() {
298
                let kind = ParseErrorKind::Expecting {
299
                    value: "digits".to_string(),
300
                };
301
                Err(ParseError::new(reader.cursor().pos, false, kind))
302
            } else {
303
596
                Ok(format!(".{digits}"))
304
            }
305
        }
306
560
        Err(_) => Ok(String::new()),
307
    }
308
}
309

            
310
1156
fn exponent(reader: &mut Reader) -> ParseResult<String> {
311
1156
    if reader.peek() == Some('e') || reader.peek() == Some('E') {
312
8
        reader.read();
313
8
        let exponent_sign = match try_literal("-", reader) {
314
            Ok(_) => "-".to_string(),
315
8
            Err(_) => match try_literal("+", reader) {
316
                Ok(_) => "+".to_string(),
317
8
                Err(_) => String::new(),
318
            },
319
        };
320
28
        let exponent_digits = reader.read_while(|c| c.is_ascii_digit());
321
8
        Ok(format!("e{exponent_sign}{exponent_digits}"))
322
    } else {
323
1148
        Ok(String::new())
324
    }
325
}
326

            
327
25780
fn expression_value_kind(reader: &mut Reader) -> ParseResult<JsonValueKind> {
328
25780
    let exp = placeholder::parse(reader)?;
329
48
    Ok(JsonValueKind::Placeholder(exp))
330
}
331

            
332
25732
fn list_value_kind(reader: &mut Reader, depth: usize) -> ParseResult<JsonValueKind> {
333
25732
    let start = reader.cursor();
334
25732
    try_literal("[", reader)?;
335
1008
    if depth >= MAX_NESTING_DEPTH {
336
4
        let kind = ParseErrorKind::Json(JsonErrorVariant::MaxDepthExceeded {
337
4
            max_depth: MAX_NESTING_DEPTH,
338
4
        });
339
4
        return Err(ParseError::new(start.pos, false, kind));
340
    }
341
1004
    let space0 = whitespace(reader);
342
1004
    let mut elements = vec![];
343

            
344
    // at least one element
345
1004
    if reader.peek() != Some(']') {
346
968
        let first_element = list_element(reader, depth + 1)?;
347
456
        elements.push(first_element);
348

            
349
        loop {
350
1376
            if reader.peek() == Some(']') {
351
448
                break;
352
            }
353
            // Reports "expecting ']'" in case the user forgot to add the last ']', e.g
354
            // `[1, 2`
355
928
            if reader.peek() != Some(',') {
356
                break;
357
            }
358
            // The reader advances after literal(","), so this saves its position to report an
359
            // error in case it happens.
360
928
            let save = reader.cursor();
361
928
            literal(",", reader)?;
362
            // If there is one more comma, e.g. [1, 2,], it's better to report to the user because
363
            // this occurrence is common.
364
3216
            if reader.peek_if(|c| !is_whitespace(c)) == Some(']') {
365
4
                let kind = ParseErrorKind::Json(JsonErrorVariant::TrailingComma);
366
4
                return Err(ParseError::new(save.pos, false, kind));
367
            }
368
924
            let element = list_element(reader, depth + 1)?;
369
920
            elements.push(element);
370
        }
371
    }
372
484
    literal("]", reader)?;
373

            
374
484
    Ok(JsonValueKind::List { space0, elements })
375
}
376

            
377
1892
fn list_element(reader: &mut Reader, depth: usize) -> ParseResult<JsonListElement> {
378
1892
    let space0 = whitespace(reader);
379
1892
    let value = parse_in_json(reader, depth)?;
380
1376
    let space1 = whitespace(reader);
381
1376
    Ok(JsonListElement {
382
1376
        space0,
383
1376
        value,
384
1376
        space1,
385
1376
    })
386
}
387

            
388
48
pub fn object_value(reader: &mut Reader, depth: usize) -> ParseResult<JsonValue> {
389
48
    let start = reader.cursor().pos;
390
48
    let kind = object_value_kind(reader, depth)?;
391
48
    Ok(JsonValue::new(
392
48
        SourceInfo::new(start, reader.cursor().pos),
393
48
        kind,
394
48
    ))
395
}
396

            
397
24772
fn object_value_kind(reader: &mut Reader, depth: usize) -> ParseResult<JsonValueKind> {
398
24772
    let start = reader.cursor();
399
24772
    try_literal("{", reader)?;
400
972
    if depth >= MAX_NESTING_DEPTH {
401
        let kind = ParseErrorKind::Json(JsonErrorVariant::MaxDepthExceeded {
402
            max_depth: MAX_NESTING_DEPTH,
403
        });
404
        return Err(ParseError::new(start.pos, false, kind));
405
    }
406
972
    let space0 = whitespace(reader);
407
972
    let mut elements = vec![];
408
972
    if reader.peek() != Some('}') {
409
908
        let first_element = object_element(reader, depth + 1)?;
410
876
        elements.push(first_element);
411

            
412
        loop {
413
2652
            if reader.peek() == Some('}') {
414
872
                break;
415
            }
416
            // Reports "expecting '}'" in case the user forgot to add the last '}', e.g
417
            // `{"name": "abc"`
418
1780
            if reader.peek() != Some(',') {
419
                break;
420
            }
421
            // The reader advances after literal(","), so this saves its position to report an
422
            // error in case it happens.
423
1780
            let save = reader.cursor();
424
1780
            literal(",", reader)?;
425
            // If there is one more comma, e.g. {"a": "b",}, it's better to report to the user
426
            // because this occurrence is common.
427
11136
            if reader.peek_if(|c| !is_whitespace(c)) == Some('}') {
428
4
                let kind = ParseErrorKind::Json(JsonErrorVariant::TrailingComma);
429
4
                return Err(ParseError::new(save.pos, false, kind));
430
            }
431
1776
            let element = object_element(reader, depth + 1)?;
432
1776
            elements.push(element);
433
        }
434
    }
435

            
436
    // at least one element
437

            
438
936
    literal("}", reader)?;
439

            
440
936
    Ok(JsonValueKind::Object { space0, elements })
441
}
442

            
443
2684
fn key(reader: &mut Reader) -> ParseResult<Template> {
444
2684
    let name = string_template(reader).map_err(|e| e.to_non_recoverable())?;
445
2684
    Ok(name)
446
}
447

            
448
2684
fn object_element(reader: &mut Reader, depth: usize) -> ParseResult<JsonObjectElement> {
449
2684
    let space0 = whitespace(reader);
450
    //literal("\"", reader)?;
451
2684
    let name = key(reader)?;
452
    //literal("\"", reader)?;
453
2684
    let space1 = whitespace(reader);
454
2684
    literal(":", reader)?;
455
2684
    let save = reader.cursor();
456
2684
    let space2 = whitespace(reader);
457
    // Checks if there is no element after ':'. In this case, a special error must be reported
458
    // because this is a common occurrence.
459
2684
    let next_char = reader.peek();
460
    // Comparing to None because `next_char` can be EOF.
461
2684
    if next_char == Some('}') || next_char.is_none() {
462
4
        let kind = ParseErrorKind::Json(JsonErrorVariant::EmptyElement);
463
4
        return Err(ParseError::new(save.pos, false, kind));
464
    }
465
2680
    let value = parse_in_json(reader, depth)?;
466
2652
    let space3 = whitespace(reader);
467
2652
    Ok(JsonObjectElement {
468
2652
        space0,
469
2652
        name,
470
2652
        space1,
471
2652
        space2,
472
2652
        value,
473
2652
        space3,
474
2652
    })
475
}
476

            
477
53036
fn is_whitespace(c: char) -> bool {
478
53036
    c == ' ' || c == '\t' || c == '\n' || c == '\r'
479
}
480

            
481
15948
fn whitespace(reader: &mut Reader) -> String {
482
15948
    reader.read_while(is_whitespace)
483
}
484

            
485
#[cfg(test)]
486
mod tests {
487
    use super::*;
488
    use crate::ast::*;
489
    use crate::reader::CharPos;
490
    use crate::types::ToSource;
491

            
492
    #[test]
493
    fn test_parse_error() {
494
        let mut reader = Reader::new("{ \"a\":\n}");
495
        let error = parse_at_depth(&mut reader, 0).err().unwrap();
496
        assert_eq!(error.pos, Pos { line: 1, column: 7 });
497
        assert_eq!(
498
            error.kind,
499
            ParseErrorKind::Json(JsonErrorVariant::EmptyElement)
500
        );
501
        assert!(!error.recoverable);
502

            
503
        let mut reader = Reader::new("[0,1,]");
504
        let error = parse_at_depth(&mut reader, 0).err().unwrap();
505
        assert_eq!(error.pos, Pos { line: 1, column: 5 });
506
        assert_eq!(
507
            error.kind,
508
            ParseErrorKind::Json(JsonErrorVariant::TrailingComma),
509
        );
510
        assert!(!error.recoverable);
511
    }
512

            
513
    #[test]
514
    fn test_max_nesting_depth() {
515
        for (opening, closing) in [("[", "]"), ("{\"a\":", "}")] {
516
            let valid = format!(
517
                "{}null{}",
518
                opening.repeat(MAX_NESTING_DEPTH),
519
                closing.repeat(MAX_NESTING_DEPTH)
520
            );
521
            let value = parse(&mut Reader::new(&valid)).unwrap();
522
            assert_eq!(value.to_source().as_str(), valid);
523
            assert_eq!(
524
                value.source_info(),
525
                &SourceInfo::new(Pos::new(1, 1), Pos::new(1, valid.len() + 1))
526
            );
527
            if opening == "{\"a\":" {
528
                assert_eq!(object_value(&mut Reader::new(&valid), 0).unwrap(), value);
529
            }
530

            
531
            let too_deep = format!(
532
                "{}null{}",
533
                opening.repeat(MAX_NESTING_DEPTH + 1),
534
                closing.repeat(MAX_NESTING_DEPTH + 1)
535
            );
536
            let error = parse(&mut Reader::new(&too_deep)).unwrap_err();
537
            assert_eq!(
538
                error.kind,
539
                ParseErrorKind::Json(JsonErrorVariant::MaxDepthExceeded {
540
                    max_depth: MAX_NESTING_DEPTH
541
                })
542
            );
543
            assert!(!error.recoverable);
544
            assert_eq!(
545
                error.pos,
546
                Pos::new(1, opening.len() * MAX_NESTING_DEPTH + 1)
547
            );
548
            if opening == "{\"a\":" {
549
                assert_eq!(
550
                    object_value(&mut Reader::new(&too_deep), 0).unwrap_err(),
551
                    error
552
                );
553
            }
554
        }
555
    }
556

            
557
    #[test]
558
    fn test_mixed_max_nesting_depth() {
559
        let valid = format!(
560
            "{}null{}",
561
            "[{\"a\":".repeat(MAX_NESTING_DEPTH / 2),
562
            "}]".repeat(MAX_NESTING_DEPTH / 2)
563
        );
564
        let value = parse(&mut Reader::new(&valid)).unwrap();
565
        assert_eq!(value.to_source().as_str(), valid);
566
        assert_eq!(
567
            value.source_info(),
568
            &SourceInfo::new(Pos::new(1, 1), Pos::new(1, valid.len() + 1))
569
        );
570

            
571
        let too_deep = format!("[{valid}]");
572
        let error = parse(&mut Reader::new(&too_deep)).unwrap_err();
573
        assert_eq!(
574
            error.kind,
575
            ParseErrorKind::Json(JsonErrorVariant::MaxDepthExceeded {
576
                max_depth: MAX_NESTING_DEPTH
577
            })
578
        );
579
        assert!(!error.recoverable);
580
    }
581

            
582
    #[test]
583
    fn test_null_value() {
584
        let mut reader = Reader::new("null");
585
        assert_eq!(
586
            null_value(&mut reader).unwrap(),
587
            JsonValue::new(
588
                SourceInfo::new(Pos::new(1, 1), Pos::new(1, 5)),
589
                JsonValueKind::Null,
590
            )
591
        );
592
        assert_eq!(reader.cursor().index, CharPos(4));
593

            
594
        let mut reader = Reader::new("true");
595
        let error = null_value(&mut reader).err().unwrap();
596
        assert_eq!(error.pos, Pos { line: 1, column: 1 });
597
        assert_eq!(
598
            error.kind,
599
            ParseErrorKind::Expecting {
600
                value: "null".to_string()
601
            }
602
        );
603
        assert!(error.recoverable);
604
    }
605

            
606
    #[test]
607
    fn test_integer() {
608
        let mut reader = Reader::new("0");
609
        assert_eq!(integer(&mut reader).unwrap(), "0".to_string());
610
        assert_eq!(reader.cursor().index, CharPos(1));
611

            
612
        let mut reader = Reader::new("123");
613
        assert_eq!(integer(&mut reader).unwrap(), "123".to_string());
614
        assert_eq!(reader.cursor().index, CharPos(3));
615

            
616
        let mut reader = Reader::new("0123");
617
        assert_eq!(integer(&mut reader).unwrap(), "0".to_string());
618
        assert_eq!(reader.cursor().index, CharPos(1));
619
    }
620

            
621
    #[test]
622
    fn test_fraction() {
623
        let mut reader = Reader::new(".5");
624
        assert_eq!(fraction(&mut reader).unwrap(), ".5".to_string());
625
        assert_eq!(reader.cursor().index, CharPos(2));
626
    }
627

            
628
    #[test]
629
    fn test_exponent() {
630
        let mut reader = Reader::new("e2");
631
        assert_eq!(exponent(&mut reader).unwrap(), "e2".to_string());
632
        assert_eq!(reader.cursor().index, CharPos(2));
633
    }
634

            
635
    #[test]
636
    fn test_boolean_value() {
637
        let mut reader = Reader::new("true");
638
        assert_eq!(
639
            boolean_value(&mut reader).unwrap().kind(),
640
            &JsonValueKind::Boolean(true)
641
        );
642
        assert_eq!(reader.cursor().index, CharPos(4));
643

            
644
        let mut reader = Reader::new("1");
645
        let error = boolean_value(&mut reader).err().unwrap();
646
        assert_eq!(error.pos, Pos { line: 1, column: 1 });
647
        assert_eq!(
648
            error.kind,
649
            ParseErrorKind::Expecting {
650
                value: "true|false".to_string()
651
            }
652
        );
653
        assert!(error.recoverable);
654
    }
655

            
656
    pub fn json_hello_world_value() -> JsonValue {
657
        // "hello\u0020{{name}}!"
658
        JsonValue::new(
659
            SourceInfo::new(Pos::new(1, 1), Pos::new(1, 23)),
660
            JsonValueKind::String(Template::new(
661
                Some('"'),
662
                vec![
663
                    TemplateElement::String {
664
                        value: "Hello ".to_string(),
665
                        source: "Hello\\u0020".to_source(),
666
                    },
667
                    TemplateElement::Placeholder(Placeholder {
668
                        space0: Whitespace {
669
                            value: String::new(),
670
                            source_info: SourceInfo::new(Pos::new(1, 15), Pos::new(1, 15)),
671
                        },
672
                        expr: Expr {
673
                            kind: ExprKind::Variable(Variable {
674
                                name: "name".to_string(),
675
                                source_info: SourceInfo::new(Pos::new(1, 15), Pos::new(1, 19)),
676
                            }),
677
                            source_info: SourceInfo::new(Pos::new(1, 15), Pos::new(1, 19)),
678
                        },
679
                        space1: Whitespace {
680
                            value: String::new(),
681
                            source_info: SourceInfo::new(Pos::new(1, 19), Pos::new(1, 19)),
682
                        },
683
                    }),
684
                    TemplateElement::String {
685
                        value: "!".to_string(),
686
                        source: "!".to_source(),
687
                    },
688
                ],
689
                SourceInfo::new(Pos::new(1, 2), Pos::new(1, 22)),
690
            )),
691
        )
692
    }
693

            
694
    #[test]
695
    fn test_string_value() {
696
        let mut reader = Reader::new("\"\"");
697
        assert_eq!(
698
            string_value_kind(&mut reader).unwrap(),
699
            JsonValueKind::String(Template::new(
700
                Some('"'),
701
                vec![],
702
                SourceInfo::new(Pos::new(1, 2), Pos::new(1, 2)),
703
            ))
704
        );
705
        assert_eq!(reader.cursor().index, CharPos(2));
706

            
707
        let mut reader = Reader::new("\"Hello\\u0020{{name}}!\"");
708
        assert_eq!(
709
            string_value_kind(&mut reader).unwrap(),
710
            json_hello_world_value().kind().clone()
711
        );
712
        assert_eq!(reader.cursor().index, CharPos(22));
713

            
714
        let mut reader = Reader::new("\"{}\"");
715
        assert_eq!(
716
            string_value_kind(&mut reader).unwrap(),
717
            JsonValueKind::String(Template::new(
718
                Some('"'),
719
                vec![TemplateElement::String {
720
                    value: "{}".to_string(),
721
                    source: "{}".to_source(),
722
                }],
723
                SourceInfo::new(Pos::new(1, 2), Pos::new(1, 4)),
724
            ))
725
        );
726
        assert_eq!(reader.cursor().index, CharPos(4));
727
    }
728

            
729
    #[test]
730
    fn test_string_value_error() {
731
        let mut reader = Reader::new("1");
732
        let error = string_value_kind(&mut reader).err().unwrap();
733
        assert_eq!(error.pos, Pos { line: 1, column: 1 });
734
        assert_eq!(
735
            error.kind,
736
            ParseErrorKind::Expecting {
737
                value: "\"".to_string()
738
            }
739
        );
740
        assert!(error.recoverable);
741

            
742
        let mut reader = Reader::new("\"1");
743
        let error = string_value_kind(&mut reader).err().unwrap();
744
        assert_eq!(error.pos, Pos { line: 1, column: 3 });
745
        assert_eq!(
746
            error.kind,
747
            ParseErrorKind::Expecting {
748
                value: "\"".to_string()
749
            }
750
        );
751
        assert!(!error.recoverable);
752

            
753
        let mut reader = Reader::new("\"{{x\"");
754
        let error = string_value_kind(&mut reader).err().unwrap();
755
        assert_eq!(error.pos, Pos { line: 1, column: 5 });
756
        assert_eq!(
757
            error.kind,
758
            ParseErrorKind::Expecting {
759
                value: "}}".to_string()
760
            }
761
        );
762
        assert!(!error.recoverable);
763
    }
764

            
765
    #[test]
766
    fn test_any_char() {
767
        let mut reader = Reader::new("a");
768
        assert_eq!(
769
            any_char(&mut reader).unwrap(),
770
            ('a', "a".to_string(), Pos { line: 1, column: 1 })
771
        );
772
        assert_eq!(reader.cursor().index, CharPos(1));
773

            
774
        let mut reader = Reader::new(" ");
775
        assert_eq!(
776
            any_char(&mut reader).unwrap(),
777
            (' ', " ".to_string(), Pos { line: 1, column: 1 })
778
        );
779
        assert_eq!(reader.cursor().index, CharPos(1));
780

            
781
        let mut reader = Reader::new("\\u0020 ");
782
        assert_eq!(
783
            any_char(&mut reader).unwrap(),
784
            (' ', "\\u0020".to_string(), Pos { line: 1, column: 1 })
785
        );
786
        assert_eq!(reader.cursor().index, CharPos(6));
787

            
788
        let mut reader = Reader::new("\\t");
789
        assert_eq!(
790
            any_char(&mut reader).unwrap(),
791
            ('\t', "\\t".to_string(), Pos { line: 1, column: 1 })
792
        );
793
        assert_eq!(reader.cursor().index, CharPos(2));
794

            
795
        let mut reader = Reader::new("#");
796
        assert_eq!(
797
            any_char(&mut reader).unwrap(),
798
            ('#', "#".to_string(), Pos { line: 1, column: 1 })
799
        );
800
        assert_eq!(reader.cursor().index, CharPos(1));
801
    }
802

            
803
    #[test]
804
    fn test_any_char_error() {
805
        let mut reader = Reader::new("");
806
        let error = any_char(&mut reader).err().unwrap();
807
        assert_eq!(error.pos, Pos { line: 1, column: 1 });
808
        assert!(error.recoverable);
809

            
810
        let mut reader = Reader::new("\t");
811
        let error = any_char(&mut reader).err().unwrap();
812
        assert_eq!(error.pos, Pos { line: 1, column: 1 });
813
        assert!(error.recoverable);
814
    }
815

            
816
    #[test]
817
    fn test_escape_char() {
818
        let mut reader = Reader::new("\\n");
819
        assert_eq!(escape_char(&mut reader).unwrap(), '\n');
820
        assert_eq!(reader.cursor().index, CharPos(2));
821

            
822
        let mut reader = Reader::new("\\u000a");
823
        assert_eq!(escape_char(&mut reader).unwrap(), '\n');
824
        assert_eq!(reader.cursor().index, CharPos(6));
825

            
826
        let mut reader = Reader::new("x");
827
        let error = escape_char(&mut reader).err().unwrap();
828
        assert_eq!(error.pos, Pos { line: 1, column: 1 });
829
        assert_eq!(
830
            error.kind,
831
            ParseErrorKind::Expecting {
832
                value: "\\".to_string()
833
            }
834
        );
835
        assert!(error.recoverable);
836
        assert_eq!(reader.cursor().index, CharPos(0));
837
    }
838

            
839
    #[test]
840
    fn test_unicode() {
841
        let mut reader = Reader::new("000a");
842
        assert_eq!(unicode(&mut reader).unwrap(), '\n');
843
        assert_eq!(reader.cursor().index, CharPos(4));
844

            
845
        let mut reader = Reader::new("c350");
846
        assert_eq!(unicode(&mut reader).unwrap(), '썐');
847
        assert_eq!(reader.cursor().index, CharPos(4));
848

            
849
        let mut reader = Reader::new("d83c\\udf78");
850
        assert_eq!(unicode(&mut reader).unwrap(), '🍸');
851
        assert_eq!(reader.cursor().index, CharPos(10));
852

            
853
        let mut reader = Reader::new("d800");
854
        let error = unicode(&mut reader).unwrap_err();
855
        assert_eq!(error.pos, Pos { line: 1, column: 5 });
856
        assert_eq!(
857
            error.kind,
858
            ParseErrorKind::Expecting {
859
                value: "\\u".to_string()
860
            }
861
        );
862
        assert!(!error.recoverable);
863

            
864
        let mut reader = Reader::new("d800\\ud800");
865
        let error = unicode(&mut reader).unwrap_err();
866
        assert_eq!(error.pos, Pos { line: 1, column: 7 });
867
        assert_eq!(error.kind, ParseErrorKind::Unicode);
868
        assert!(!error.recoverable);
869
    }
870

            
871
    #[test]
872
    fn test_hex_value() {
873
        let mut reader = Reader::new("0020x");
874
        assert_eq!(hex_value(&mut reader).unwrap(), 32);
875

            
876
        let mut reader = Reader::new("d800");
877
        assert_eq!(hex_value(&mut reader).unwrap(), 55296);
878

            
879
        let mut reader = Reader::new("x");
880
        let error = hex_value(&mut reader).unwrap_err();
881
        assert_eq!(error.pos, Pos { line: 1, column: 1 });
882
        assert_eq!(error.kind, ParseErrorKind::HexDigit);
883
        assert!(!error.recoverable);
884
    }
885

            
886
    #[test]
887
    fn test_number_value() {
888
        let mut reader = Reader::new("100");
889
        assert_eq!(
890
            number_value(&mut reader).unwrap(),
891
            JsonValue::new(
892
                SourceInfo::new(Pos::new(1, 1), Pos::new(1, 4)),
893
                JsonValueKind::Number("100".to_string()),
894
            )
895
        );
896
        assert_eq!(reader.cursor().index, CharPos(3));
897

            
898
        let mut reader = Reader::new("1.333");
899
        assert_eq!(
900
            number_value(&mut reader).unwrap(),
901
            JsonValue::new(
902
                SourceInfo::new(Pos::new(1, 1), Pos::new(1, 6)),
903
                JsonValueKind::Number("1.333".to_string()),
904
            )
905
        );
906
        assert_eq!(reader.cursor().index, CharPos(5));
907

            
908
        let mut reader = Reader::new("-1");
909
        assert_eq!(
910
            number_value(&mut reader).unwrap(),
911
            JsonValue::new(
912
                SourceInfo::new(Pos::new(1, 1), Pos::new(1, 3)),
913
                JsonValueKind::Number("-1".to_string()),
914
            )
915
        );
916
        assert_eq!(reader.cursor().index, CharPos(2));
917

            
918
        let mut reader = Reader::new("00");
919
        assert_eq!(
920
            number_value(&mut reader).unwrap(),
921
            JsonValue::new(
922
                SourceInfo::new(Pos::new(1, 1), Pos::new(1, 2)),
923
                JsonValueKind::Number("0".to_string()),
924
            )
925
        );
926
        assert_eq!(reader.cursor().index, CharPos(1));
927

            
928
        let mut reader = Reader::new("1e0");
929
        assert_eq!(
930
            number_value(&mut reader).unwrap(),
931
            JsonValue::new(
932
                SourceInfo::new(Pos::new(1, 1), Pos::new(1, 4)),
933
                JsonValueKind::Number("1e0".to_string()),
934
            )
935
        );
936
        assert_eq!(reader.cursor().index, CharPos(3));
937

            
938
        let mut reader = Reader::new("1e005");
939
        assert_eq!(
940
            number_value(&mut reader).unwrap(),
941
            JsonValue::new(
942
                SourceInfo::new(Pos::new(1, 1), Pos::new(1, 6)),
943
                JsonValueKind::Number("1e005".to_string()),
944
            )
945
        );
946
        assert_eq!(reader.cursor().index, CharPos(5));
947

            
948
        let mut reader = Reader::new("1e-005");
949
        assert_eq!(
950
            number_value(&mut reader).unwrap(),
951
            JsonValue::new(
952
                SourceInfo::new(Pos::new(1, 1), Pos::new(1, 7)),
953
                JsonValueKind::Number("1e-005".to_string()),
954
            )
955
        );
956
        assert_eq!(reader.cursor().index, CharPos(6));
957
    }
958

            
959
    #[test]
960
    fn test_number_value_error() {
961
        let mut reader = Reader::new("true");
962
        let error = number_value(&mut reader).err().unwrap();
963
        assert_eq!(error.pos, Pos { line: 1, column: 1 });
964
        assert_eq!(
965
            error.kind,
966
            ParseErrorKind::Expecting {
967
                value: "number".to_string()
968
            }
969
        );
970
        assert!(error.recoverable);
971

            
972
        let mut reader = Reader::new("1.x");
973
        let error = number_value(&mut reader).err().unwrap();
974
        assert_eq!(error.pos, Pos { line: 1, column: 3 });
975
        assert_eq!(
976
            error.kind,
977
            ParseErrorKind::Expecting {
978
                value: "digits".to_string()
979
            }
980
        );
981
        assert!(!error.recoverable);
982
    }
983

            
984
    #[test]
985
    fn test_expression_value() {
986
        let mut reader = Reader::new("{{n}}");
987
        assert_eq!(
988
            expression_value_kind(&mut reader).unwrap(),
989
            JsonValueKind::Placeholder(Placeholder {
990
                space0: Whitespace {
991
                    value: String::new(),
992
                    source_info: SourceInfo::new(Pos::new(1, 3), Pos::new(1, 3))
993
                },
994
                expr: Expr {
995
                    kind: ExprKind::Variable(Variable {
996
                        name: "n".to_string(),
997
                        source_info: SourceInfo::new(Pos::new(1, 3), Pos::new(1, 4))
998
                    }),
999
                    source_info: SourceInfo::new(Pos::new(1, 3), Pos::new(1, 4))
                },
                space1: Whitespace {
                    value: String::new(),
                    source_info: SourceInfo::new(Pos::new(1, 4), Pos::new(1, 4))
                }
            })
        );
        assert_eq!(reader.cursor().index, CharPos(5));
    }
    #[test]
    fn test_list_value() {
        let mut reader = Reader::new("[]");
        assert_eq!(
            list_value_kind(&mut reader, 0).unwrap(),
            JsonValueKind::List {
                space0: String::new(),
                elements: vec![]
            }
        );
        assert_eq!(reader.cursor().index, CharPos(2));
        let mut reader = Reader::new("[ ]");
        assert_eq!(
            list_value_kind(&mut reader, 0).unwrap(),
            JsonValueKind::List {
                space0: " ".to_string(),
                elements: vec![]
            }
        );
        assert_eq!(reader.cursor().index, CharPos(3));
        let mut reader = Reader::new("[true, false]");
        assert_eq!(
            list_value_kind(&mut reader, 0).unwrap(),
            JsonValueKind::List {
                space0: String::new(),
                elements: vec![
                    JsonListElement {
                        space0: String::new(),
                        value: JsonValue::new(
                            SourceInfo::new(Pos::new(1, 2), Pos::new(1, 6)),
                            JsonValueKind::Boolean(true),
                        ),
                        space1: String::new(),
                    },
                    JsonListElement {
                        space0: String::from(" "),
                        value: JsonValue::new(
                            SourceInfo::new(Pos::new(1, 8), Pos::new(1, 13)),
                            JsonValueKind::Boolean(false),
                        ),
                        space1: String::new(),
                    }
                ],
            }
        );
        assert_eq!(reader.cursor().index, CharPos(13));
    }
    #[test]
    fn test_list_error() {
        let mut reader = Reader::new("true");
        let error = list_value_kind(&mut reader, 0).err().unwrap();
        assert_eq!(error.pos, Pos { line: 1, column: 1 });
        assert_eq!(
            error.kind,
            ParseErrorKind::Expecting {
                value: "[".to_string()
            }
        );
        assert!(error.recoverable);
        let mut reader = Reader::new("[1, 2,]");
        let error = list_value_kind(&mut reader, 0).err().unwrap();
        assert_eq!(error.pos, Pos { line: 1, column: 6 });
        assert_eq!(
            error.kind,
            ParseErrorKind::Json(JsonErrorVariant::TrailingComma),
        );
        assert!(!error.recoverable);
    }
    #[test]
    fn test_list_element() {
        let mut reader = Reader::new("true");
        assert_eq!(
            list_element(&mut reader, 1).unwrap(),
            JsonListElement {
                space0: String::new(),
                value: JsonValue::new(
                    SourceInfo::new(Pos::new(1, 1), Pos::new(1, 5)),
                    JsonValueKind::Boolean(true),
                ),
                space1: String::new(),
            }
        );
        assert_eq!(reader.cursor().index, CharPos(4));
    }
    #[test]
    fn test_object_value() {
        let mut reader = Reader::new("{}");
        assert_eq!(
            object_value(&mut reader, 0).unwrap(),
            JsonValue::new(
                SourceInfo::new(Pos::new(1, 1), Pos::new(1, 3)),
                JsonValueKind::Object {
                    space0: String::new(),
                    elements: vec![]
                },
            )
        );
        assert_eq!(reader.cursor().index, CharPos(2));
        let mut reader = Reader::new("{ }");
        assert_eq!(
            object_value(&mut reader, 0).unwrap(),
            JsonValue::new(
                SourceInfo::new(Pos::new(1, 1), Pos::new(1, 4)),
                JsonValueKind::Object {
                    space0: " ".to_string(),
                    elements: vec![]
                },
            )
        );
        assert_eq!(reader.cursor().index, CharPos(3));
        let mut reader = Reader::new("{\n  \"a\": true\n}");
        assert_eq!(
            object_value(&mut reader, 0).unwrap(),
            JsonValue::new(
                SourceInfo::new(Pos::new(1, 1), Pos::new(3, 2)),
                JsonValueKind::Object {
                    space0: "\n  ".to_string(),
                    elements: vec![JsonObjectElement {
                        space0: String::new(),
                        name: Template::new(
                            Some('"'),
                            vec![TemplateElement::String {
                                value: "a".to_string(),
                                source: "a".to_source()
                            }],
                            SourceInfo::new(Pos::new(2, 4), Pos::new(2, 5))
                        ),
                        space1: String::new(),
                        space2: " ".to_string(),
                        value: JsonValue::new(
                            SourceInfo::new(Pos::new(2, 8), Pos::new(2, 12)),
                            JsonValueKind::Boolean(true),
                        ),
                        space3: "\n".to_string(),
                    }],
                },
            )
        );
        assert_eq!(reader.cursor().index, CharPos(15));
        let mut reader = Reader::new("true");
        let error = object_value(&mut reader, 0).err().unwrap();
        assert_eq!(error.pos, Pos { line: 1, column: 1 });
        assert_eq!(
            error.kind,
            ParseErrorKind::Expecting {
                value: "{".to_string()
            }
        );
        assert!(error.recoverable);
    }
    #[test]
    fn test_object_error() {
        let mut reader = Reader::new("{ \"a\":\n}");
        let error = object_value(&mut reader, 0).err().unwrap();
        assert_eq!(error.pos, Pos { line: 1, column: 7 });
        assert_eq!(
            error.kind,
            ParseErrorKind::Json(JsonErrorVariant::EmptyElement)
        );
        assert!(!error.recoverable);
    }
    #[test]
    fn test_object_element() {
        let mut reader = Reader::new("\"a\": true");
        assert_eq!(
            object_element(&mut reader, 1).unwrap(),
            JsonObjectElement {
                space0: String::new(),
                name: Template::new(
                    Some('"'),
                    vec![TemplateElement::String {
                        value: "a".to_string(),
                        source: "a".to_source()
                    }],
                    SourceInfo::new(Pos::new(1, 2), Pos::new(1, 3))
                ),
                space1: String::new(),
                space2: " ".to_string(),
                value: JsonValue::new(
                    SourceInfo::new(Pos::new(1, 6), Pos::new(1, 10)),
                    JsonValueKind::Boolean(true),
                ),
                space3: String::new(),
            }
        );
        assert_eq!(reader.cursor().index, CharPos(9));
    }
    #[test]
    fn test_object_element_error() {
        let mut reader = Reader::new(":");
        let error = object_element(&mut reader, 1).err().unwrap();
        assert_eq!(error.pos, Pos { line: 1, column: 1 });
        assert_eq!(
            error.kind,
            ParseErrorKind::Expecting {
                value: "\"".to_string()
            }
        );
        assert!(!error.recoverable);
        let mut reader = Reader::new("\"name\":\n");
        let error = object_element(&mut reader, 1).err().unwrap();
        assert_eq!(error.pos, Pos { line: 1, column: 8 });
        assert_eq!(
            error.kind,
            ParseErrorKind::Json(JsonErrorVariant::EmptyElement),
        );
        assert!(!error.recoverable);
    }
    #[test]
    fn test_whitespace() {
        let mut reader = Reader::new("");
        assert_eq!(whitespace(&mut reader), String::new());
        assert_eq!(reader.cursor().index, CharPos(0));
        let mut reader = Reader::new(" x");
        assert_eq!(whitespace(&mut reader), " ".to_string());
        assert_eq!(reader.cursor().index, CharPos(1));
        let mut reader = Reader::new("\n  x");
        assert_eq!(whitespace(&mut reader), "\n  ".to_string());
        assert_eq!(reader.cursor().index, CharPos(3));
    }
}