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 super::placeholder;
19
use crate::ast::{JsonListElement, JsonObjectElement, JsonValue, SourceInfo, Template};
20
use crate::combinator::{ParseError as ParseErrorTrait, choice, non_recover};
21
use crate::parser::primitives::{boolean, hex_digit, literal, try_literal};
22
use crate::parser::template::EncodedString;
23
use crate::parser::{JsonErrorVariant, ParseError, ParseErrorKind, ParseResult, templatize};
24
use crate::reader::{Pos, Reader};
25

            
26
const MAX_NESTING_DEPTH: usize = 128;
27

            
28
/// Parse a JSON value from the reader.
29
24156
pub fn parse(reader: &mut Reader) -> ParseResult<JsonValue> {
30
24156
    parse_at_depth(reader, 0)
31
}
32

            
33
/// Parse a JSON value from the reader, considering the current nesting depth.
34
28728
fn parse_at_depth(reader: &mut Reader, depth: usize) -> ParseResult<JsonValue> {
35
28728
    let parsers = [
36
28728
        null_value,
37
28728
        boolean_value,
38
28728
        string_value,
39
28728
        number_value,
40
28728
        expression_value,
41
28728
    ];
42
28728
    let start = reader.cursor();
43
28728
    match choice(&parsers, reader) {
44
25640
        Err(error) if error.recoverable => reader.seek(start),
45
3088
        result => return result,
46
    }
47

            
48
25640
    let start = reader.cursor();
49
25640
    match list_value(reader, depth) {
50
24632
        Err(error) if error.recoverable => reader.seek(start),
51
1008
        result => return result,
52
    }
53
24632
    object_value(reader, depth)
54
}
55

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

            
81
28744
pub fn null_value(reader: &mut Reader) -> ParseResult<JsonValue> {
82
28744
    try_literal("null", reader)?;
83
40
    Ok(JsonValue::Null)
84
}
85

            
86
28712
pub fn boolean_value(reader: &mut Reader) -> ParseResult<JsonValue> {
87
28712
    let value = boolean(reader)?;
88
136
    Ok(JsonValue::Boolean(value))
89
}
90

            
91
28560
fn string_value(reader: &mut Reader) -> ParseResult<JsonValue> {
92
28560
    let template = string_template(reader)?;
93
1720
    Ok(JsonValue::String(template))
94
}
95

            
96
31244
fn string_template(reader: &mut Reader) -> ParseResult<Template> {
97
31244
    try_literal("\"", reader)?;
98
4412
    let delimiter = Some('"');
99
4412
    let mut chars = vec![];
100
4412
    let start = reader.cursor();
101
    loop {
102
41000
        if reader.peek() == Some('"') || reader.is_eof() {
103
4404
            break;
104
        }
105
36596
        let char = any_char(reader)?;
106
36588
        chars.push(char);
107
    }
108
4404
    let end = reader.cursor();
109

            
110
4404
    let encoded_string = EncodedString {
111
4404
        source_info: SourceInfo::new(start.pos, end.pos),
112
4404
        chars,
113
4404
    };
114
4404
    literal("\"", reader)?;
115
4404
    let elements = templatize(encoded_string)?;
116

            
117
4404
    let template = Template::new(delimiter, elements, SourceInfo::new(start.pos, end.pos));
118
4404
    Ok(template)
119
}
120

            
121
36596
fn any_char(reader: &mut Reader) -> ParseResult<(char, String, Pos)> {
122
36596
    let start = reader.cursor();
123
36596
    match escape_char(reader) {
124
312
        Ok(c) => Ok((c, reader.read_from(start.index), start.pos)),
125
36284
        Err(e) => {
126
36284
            if e.recoverable {
127
36276
                reader.seek(start);
128
36276
                match reader.read() {
129
                    None => {
130
                        let kind = ParseErrorKind::Expecting {
131
                            value: "char".to_string(),
132
                        };
133
                        Err(ParseError::new(start.pos, true, kind))
134
                    }
135
36276
                    Some(c) => {
136
36276
                        if ['\\', '\x08', '\n', '\x0c', '\r', '\t'].contains(&c) {
137
                            let kind = ParseErrorKind::Expecting {
138
                                value: "char".to_string(),
139
                            };
140
                            Err(ParseError::new(start.pos, true, kind))
141
                        } else {
142
36276
                            Ok((c, reader.read_from(start.index), start.pos))
143
                        }
144
                    }
145
                }
146
            } else {
147
8
                Err(e)
148
            }
149
        }
150
    }
151
}
152

            
153
36596
fn escape_char(reader: &mut Reader) -> ParseResult<char> {
154
36596
    try_literal("\\", reader)?;
155
320
    let start = reader.cursor();
156
320
    match reader.read() {
157
164
        Some('"') => Ok('"'),
158
8
        Some('\\') => Ok('\\'),
159
        Some('/') => Ok('/'),
160
        Some('b') => Ok('\x08'),
161
132
        Some('n') => Ok('\n'),
162
        Some('f') => Ok('\x0c'),
163
        Some('r') => Ok('\r'),
164
4
        Some('t') => Ok('\t'),
165
12
        Some('u') => unicode(reader),
166
        _ => Err(ParseError::new(
167
            start.pos,
168
            false,
169
            ParseErrorKind::EscapeChar,
170
        )),
171
    }
172
}
173

            
174
12
fn unicode(reader: &mut Reader) -> ParseResult<char> {
175
12
    let start = reader.cursor();
176
12
    let cp1 = hex_value(reader)?;
177
8
    let cp = if is_surrogate(cp1) {
178
8
        literal("\\u", reader)?;
179
8
        let start = reader.cursor();
180
8
        let cp2 = hex_value(reader)?;
181
8
        match cp_surrogate_pair(cp1, cp2) {
182
4
            None => return Err(ParseError::new(start.pos, false, ParseErrorKind::Unicode)),
183
4
            Some(cp) => cp,
184
        }
185
    } else {
186
        cp1
187
    };
188
4
    let c = match char::from_u32(cp) {
189
        None => return Err(ParseError::new(start.pos, false, ParseErrorKind::Unicode)),
190
4
        Some(c) => c,
191
    };
192
4
    Ok(c)
193
}
194

            
195
// 0xd800-0xdc00 encodes the high 10 bits of a pair.
196
// 0xdc00-0xe000 encodes the low 10 bits of a pair.
197
// the value is those 20 bits plus 0x10000.
198
const SURR1: u32 = 0xd800;
199
const SURR2: u32 = 0xdc00;
200
const SURR3: u32 = 0xe000;
201
const SURR_SELF: u32 = 0x10000;
202

            
203
/// Returns whether the specified Unicode code point can appear in a surrogate pair.
204
8
fn is_surrogate(cp: u32) -> bool {
205
8
    (SURR1..SURR3).contains(&cp)
206
}
207

            
208
8
fn cp_surrogate_pair(cp1: u32, cp2: u32) -> Option<u32> {
209
8
    if (SURR1..SURR2).contains(&cp1) && (SURR2..SURR3).contains(&cp2) {
210
4
        Some(((cp1 - SURR1) << 10) | ((cp2 - SURR2) + SURR_SELF))
211
    } else {
212
4
        None
213
    }
214
}
215

            
216
20
fn hex_value(reader: &mut Reader) -> ParseResult<u32> {
217
20
    let digit1 = non_recover(hex_digit, reader)?;
218
20
    let digit2 = non_recover(hex_digit, reader)?;
219
20
    let digit3 = non_recover(hex_digit, reader)?;
220
20
    let digit4 = non_recover(hex_digit, reader)?;
221
16
    let value = digit1 * (16 * 16 * 16) + digit2 * (16 * 16) + digit3 * 16 + digit4;
222
16
    Ok(value)
223
}
224

            
225
26864
pub fn number_value(reader: &mut Reader) -> ParseResult<JsonValue> {
226
26864
    let sign = match try_literal("-", reader) {
227
26828
        Err(_) => String::new(),
228
36
        Ok(_) => "-".to_string(),
229
    };
230
26864
    let int = integer(reader)?;
231
1156
    let frac = fraction(reader)?;
232
1156
    let exp = exponent(reader)?;
233
1156
    Ok(JsonValue::Number(format!("{sign}{int}{frac}{exp}")))
234
}
235

            
236
26864
fn integer(reader: &mut Reader) -> ParseResult<String> {
237
26864
    let start = reader.cursor();
238
26864
    match try_literal("0", reader) {
239
        Err(_) => {
240
26656
            let digits = reader.read_while(|c| c.is_ascii_digit());
241
26656
            if digits.is_empty() {
242
25708
                let kind = ParseErrorKind::Expecting {
243
25708
                    value: "number".to_string(),
244
25708
                };
245
25708
                Err(ParseError::new(start.pos, true, kind))
246
            } else {
247
948
                Ok(digits)
248
            }
249
        }
250
208
        Ok(_) => Ok("0".to_string()),
251
    }
252
}
253

            
254
1156
fn fraction(reader: &mut Reader) -> ParseResult<String> {
255
1156
    match try_literal(".", reader) {
256
        Ok(_) => {
257
3576
            let digits = reader.read_while(|c| c.is_ascii_digit());
258
596
            if digits.is_empty() {
259
                let kind = ParseErrorKind::Expecting {
260
                    value: "digits".to_string(),
261
                };
262
                Err(ParseError::new(reader.cursor().pos, false, kind))
263
            } else {
264
596
                Ok(format!(".{digits}"))
265
            }
266
        }
267
560
        Err(_) => Ok(String::new()),
268
    }
269
}
270

            
271
1156
fn exponent(reader: &mut Reader) -> ParseResult<String> {
272
1156
    if reader.peek() == Some('e') || reader.peek() == Some('E') {
273
8
        reader.read();
274
8
        let exponent_sign = match try_literal("-", reader) {
275
            Ok(_) => "-".to_string(),
276
8
            Err(_) => match try_literal("+", reader) {
277
                Ok(_) => "+".to_string(),
278
8
                Err(_) => String::new(),
279
            },
280
        };
281
28
        let exponent_digits = reader.read_while(|c| c.is_ascii_digit());
282
8
        Ok(format!("e{exponent_sign}{exponent_digits}"))
283
    } else {
284
1148
        Ok(String::new())
285
    }
286
}
287

            
288
25688
fn expression_value(reader: &mut Reader) -> ParseResult<JsonValue> {
289
25688
    let exp = placeholder::parse(reader)?;
290
48
    Ok(JsonValue::Placeholder(exp))
291
}
292

            
293
25640
fn list_value(reader: &mut Reader, depth: usize) -> ParseResult<JsonValue> {
294
25640
    let start = reader.cursor();
295
25640
    try_literal("[", reader)?;
296
1008
    if depth >= MAX_NESTING_DEPTH {
297
4
        let kind = ParseErrorKind::Json(JsonErrorVariant::MaxDepthExceeded {
298
4
            max_depth: MAX_NESTING_DEPTH,
299
4
        });
300
4
        return Err(ParseError::new(start.pos, false, kind));
301
    }
302
1004
    let space0 = whitespace(reader);
303
1004
    let mut elements = vec![];
304

            
305
    // at least one element
306
1004
    if reader.peek() != Some(']') {
307
968
        let first_element = list_element(reader, depth + 1)?;
308
456
        elements.push(first_element);
309

            
310
        loop {
311
1376
            if reader.peek() == Some(']') {
312
448
                break;
313
            }
314
            // Reports "expecting ']'" in case the user forgot to add the last ']', e.g
315
            // `[1, 2`
316
928
            if reader.peek() != Some(',') {
317
                break;
318
            }
319
            // The reader advances after literal(","), so this saves its position to report an
320
            // error in case it happens.
321
928
            let save = reader.cursor();
322
928
            literal(",", reader)?;
323
            // If there is one more comma, e.g. [1, 2,], it's better to report to the user because
324
            // this occurrence is common.
325
3216
            if reader.peek_if(|c| !is_whitespace(c)) == Some(']') {
326
4
                let kind = ParseErrorKind::Json(JsonErrorVariant::TrailingComma);
327
4
                return Err(ParseError::new(save.pos, false, kind));
328
            }
329
924
            let element = list_element(reader, depth + 1)?;
330
920
            elements.push(element);
331
        }
332
    }
333
484
    literal("]", reader)?;
334

            
335
484
    Ok(JsonValue::List { space0, elements })
336
}
337

            
338
1892
fn list_element(reader: &mut Reader, depth: usize) -> ParseResult<JsonListElement> {
339
1892
    let space0 = whitespace(reader);
340
1892
    let value = parse_in_json(reader, depth)?;
341
1376
    let space1 = whitespace(reader);
342
1376
    Ok(JsonListElement {
343
1376
        space0,
344
1376
        value,
345
1376
        space1,
346
1376
    })
347
}
348

            
349
24680
pub fn object_value(reader: &mut Reader, depth: usize) -> ParseResult<JsonValue> {
350
24680
    let start = reader.cursor();
351
24680
    try_literal("{", reader)?;
352
972
    if depth >= MAX_NESTING_DEPTH {
353
        let kind = ParseErrorKind::Json(JsonErrorVariant::MaxDepthExceeded {
354
            max_depth: MAX_NESTING_DEPTH,
355
        });
356
        return Err(ParseError::new(start.pos, false, kind));
357
    }
358
972
    let space0 = whitespace(reader);
359
972
    let mut elements = vec![];
360
972
    if reader.peek() != Some('}') {
361
908
        let first_element = object_element(reader, depth + 1)?;
362
876
        elements.push(first_element);
363

            
364
        loop {
365
2652
            if reader.peek() == Some('}') {
366
872
                break;
367
            }
368
            // Reports "expecting '}'" in case the user forgot to add the last '}', e.g
369
            // `{"name": "abc"`
370
1780
            if reader.peek() != Some(',') {
371
                break;
372
            }
373
            // The reader advances after literal(","), so this saves its position to report an
374
            // error in case it happens.
375
1780
            let save = reader.cursor();
376
1780
            literal(",", reader)?;
377
            // If there is one more comma, e.g. {"a": "b",}, it's better to report to the user
378
            // because this occurrence is common.
379
11136
            if reader.peek_if(|c| !is_whitespace(c)) == Some('}') {
380
4
                let kind = ParseErrorKind::Json(JsonErrorVariant::TrailingComma);
381
4
                return Err(ParseError::new(save.pos, false, kind));
382
            }
383
1776
            let element = object_element(reader, depth + 1)?;
384
1776
            elements.push(element);
385
        }
386
    }
387

            
388
    // at least one element
389

            
390
936
    literal("}", reader)?;
391

            
392
936
    Ok(JsonValue::Object { space0, elements })
393
}
394

            
395
2684
fn key(reader: &mut Reader) -> ParseResult<Template> {
396
2684
    let name = string_template(reader).map_err(|e| e.to_non_recoverable())?;
397
2684
    Ok(name)
398
}
399

            
400
2684
fn object_element(reader: &mut Reader, depth: usize) -> ParseResult<JsonObjectElement> {
401
2684
    let space0 = whitespace(reader);
402
    //literal("\"", reader)?;
403
2684
    let name = key(reader)?;
404
    //literal("\"", reader)?;
405
2684
    let space1 = whitespace(reader);
406
2684
    literal(":", reader)?;
407
2684
    let save = reader.cursor();
408
2684
    let space2 = whitespace(reader);
409
    // Checks if there is no element after ':'. In this case, a special error must be reported
410
    // because this is a common occurrence.
411
2684
    let next_char = reader.peek();
412
    // Comparing to None because `next_char` can be EOF.
413
2684
    if next_char == Some('}') || next_char.is_none() {
414
4
        let kind = ParseErrorKind::Json(JsonErrorVariant::EmptyElement);
415
4
        return Err(ParseError::new(save.pos, false, kind));
416
    }
417
2680
    let value = parse_in_json(reader, depth)?;
418
2652
    let space3 = whitespace(reader);
419
2652
    Ok(JsonObjectElement {
420
2652
        space0,
421
2652
        name,
422
2652
        space1,
423
2652
        space2,
424
2652
        value,
425
2652
        space3,
426
2652
    })
427
}
428

            
429
53036
fn is_whitespace(c: char) -> bool {
430
53036
    c == ' ' || c == '\t' || c == '\n' || c == '\r'
431
}
432

            
433
15948
fn whitespace(reader: &mut Reader) -> String {
434
15948
    reader.read_while(is_whitespace)
435
}
436

            
437
#[cfg(test)]
438
mod tests {
439
    use super::*;
440
    use crate::ast::*;
441
    use crate::reader::CharPos;
442
    use crate::types::ToSource;
443

            
444
    #[test]
445
    fn test_parse_error() {
446
        let mut reader = Reader::new("{ \"a\":\n}");
447
        let error = parse_at_depth(&mut reader, 0).err().unwrap();
448
        assert_eq!(error.pos, Pos { line: 1, column: 7 });
449
        assert_eq!(
450
            error.kind,
451
            ParseErrorKind::Json(JsonErrorVariant::EmptyElement)
452
        );
453
        assert!(!error.recoverable);
454

            
455
        let mut reader = Reader::new("[0,1,]");
456
        let error = parse_at_depth(&mut reader, 0).err().unwrap();
457
        assert_eq!(error.pos, Pos { line: 1, column: 5 });
458
        assert_eq!(
459
            error.kind,
460
            ParseErrorKind::Json(JsonErrorVariant::TrailingComma),
461
        );
462
        assert!(!error.recoverable);
463
    }
464

            
465
    #[test]
466
    fn test_max_nesting_depth() {
467
        for (opening, closing) in [("[", "]"), ("{\"a\":", "}")] {
468
            let valid = format!(
469
                "{}null{}",
470
                opening.repeat(MAX_NESTING_DEPTH),
471
                closing.repeat(MAX_NESTING_DEPTH)
472
            );
473
            assert!(parse_at_depth(&mut Reader::new(&valid), 0).is_ok());
474

            
475
            let too_deep = format!(
476
                "{}null{}",
477
                opening.repeat(MAX_NESTING_DEPTH + 1),
478
                closing.repeat(MAX_NESTING_DEPTH + 1)
479
            );
480
            let error = parse_at_depth(&mut Reader::new(&too_deep), 0).unwrap_err();
481
            assert_eq!(
482
                error.kind,
483
                ParseErrorKind::Json(JsonErrorVariant::MaxDepthExceeded {
484
                    max_depth: MAX_NESTING_DEPTH
485
                })
486
            );
487
        }
488
    }
489

            
490
    #[test]
491
    fn test_null_value() {
492
        let mut reader = Reader::new("null");
493
        assert_eq!(null_value(&mut reader).unwrap(), JsonValue::Null);
494
        assert_eq!(reader.cursor().index, CharPos(4));
495

            
496
        let mut reader = Reader::new("true");
497
        let error = null_value(&mut reader).err().unwrap();
498
        assert_eq!(error.pos, Pos { line: 1, column: 1 });
499
        assert_eq!(
500
            error.kind,
501
            ParseErrorKind::Expecting {
502
                value: "null".to_string()
503
            }
504
        );
505
        assert!(error.recoverable);
506
    }
507

            
508
    #[test]
509
    fn test_integer() {
510
        let mut reader = Reader::new("0");
511
        assert_eq!(integer(&mut reader).unwrap(), "0".to_string());
512
        assert_eq!(reader.cursor().index, CharPos(1));
513

            
514
        let mut reader = Reader::new("123");
515
        assert_eq!(integer(&mut reader).unwrap(), "123".to_string());
516
        assert_eq!(reader.cursor().index, CharPos(3));
517

            
518
        let mut reader = Reader::new("0123");
519
        assert_eq!(integer(&mut reader).unwrap(), "0".to_string());
520
        assert_eq!(reader.cursor().index, CharPos(1));
521
    }
522

            
523
    #[test]
524
    fn test_fraction() {
525
        let mut reader = Reader::new(".5");
526
        assert_eq!(fraction(&mut reader).unwrap(), ".5".to_string());
527
        assert_eq!(reader.cursor().index, CharPos(2));
528
    }
529

            
530
    #[test]
531
    fn test_exponent() {
532
        let mut reader = Reader::new("e2");
533
        assert_eq!(exponent(&mut reader).unwrap(), "e2".to_string());
534
        assert_eq!(reader.cursor().index, CharPos(2));
535
    }
536

            
537
    #[test]
538
    fn test_boolean_value() {
539
        let mut reader = Reader::new("true");
540
        assert_eq!(
541
            boolean_value(&mut reader).unwrap(),
542
            JsonValue::Boolean(true)
543
        );
544
        assert_eq!(reader.cursor().index, CharPos(4));
545

            
546
        let mut reader = Reader::new("1");
547
        let error = boolean_value(&mut reader).err().unwrap();
548
        assert_eq!(error.pos, Pos { line: 1, column: 1 });
549
        assert_eq!(
550
            error.kind,
551
            ParseErrorKind::Expecting {
552
                value: "true|false".to_string()
553
            }
554
        );
555
        assert!(error.recoverable);
556
    }
557

            
558
    pub fn json_hello_world_value() -> JsonValue {
559
        // "hello\u0020{{name}}!"
560
        JsonValue::String(Template::new(
561
            Some('"'),
562
            vec![
563
                TemplateElement::String {
564
                    value: "Hello ".to_string(),
565
                    source: "Hello\\u0020".to_source(),
566
                },
567
                TemplateElement::Placeholder(Placeholder {
568
                    space0: Whitespace {
569
                        value: String::new(),
570
                        source_info: SourceInfo::new(Pos::new(1, 15), Pos::new(1, 15)),
571
                    },
572
                    expr: Expr {
573
                        kind: ExprKind::Variable(Variable {
574
                            name: "name".to_string(),
575
                            source_info: SourceInfo::new(Pos::new(1, 15), Pos::new(1, 19)),
576
                        }),
577
                        source_info: SourceInfo::new(Pos::new(1, 15), Pos::new(1, 19)),
578
                    },
579
                    space1: Whitespace {
580
                        value: String::new(),
581
                        source_info: SourceInfo::new(Pos::new(1, 19), Pos::new(1, 19)),
582
                    },
583
                }),
584
                TemplateElement::String {
585
                    value: "!".to_string(),
586
                    source: "!".to_source(),
587
                },
588
            ],
589
            SourceInfo::new(Pos::new(1, 2), Pos::new(1, 22)),
590
        ))
591
    }
592

            
593
    #[test]
594
    fn test_string_value() {
595
        let mut reader = Reader::new("\"\"");
596
        assert_eq!(
597
            string_value(&mut reader).unwrap(),
598
            JsonValue::String(Template::new(
599
                Some('"'),
600
                vec![],
601
                SourceInfo::new(Pos::new(1, 2), Pos::new(1, 2)),
602
            ))
603
        );
604
        assert_eq!(reader.cursor().index, CharPos(2));
605

            
606
        let mut reader = Reader::new("\"Hello\\u0020{{name}}!\"");
607
        assert_eq!(string_value(&mut reader).unwrap(), json_hello_world_value());
608
        assert_eq!(reader.cursor().index, CharPos(22));
609

            
610
        let mut reader = Reader::new("\"{}\"");
611
        assert_eq!(
612
            string_value(&mut reader).unwrap(),
613
            JsonValue::String(Template::new(
614
                Some('"'),
615
                vec![TemplateElement::String {
616
                    value: "{}".to_string(),
617
                    source: "{}".to_source(),
618
                }],
619
                SourceInfo::new(Pos::new(1, 2), Pos::new(1, 4)),
620
            ))
621
        );
622
        assert_eq!(reader.cursor().index, CharPos(4));
623
    }
624

            
625
    #[test]
626
    fn test_string_value_error() {
627
        let mut reader = Reader::new("1");
628
        let error = string_value(&mut reader).err().unwrap();
629
        assert_eq!(error.pos, Pos { line: 1, column: 1 });
630
        assert_eq!(
631
            error.kind,
632
            ParseErrorKind::Expecting {
633
                value: "\"".to_string()
634
            }
635
        );
636
        assert!(error.recoverable);
637

            
638
        let mut reader = Reader::new("\"1");
639
        let error = string_value(&mut reader).err().unwrap();
640
        assert_eq!(error.pos, Pos { line: 1, column: 3 });
641
        assert_eq!(
642
            error.kind,
643
            ParseErrorKind::Expecting {
644
                value: "\"".to_string()
645
            }
646
        );
647
        assert!(!error.recoverable);
648

            
649
        let mut reader = Reader::new("\"{{x\"");
650
        let error = string_value(&mut reader).err().unwrap();
651
        assert_eq!(error.pos, Pos { line: 1, column: 5 });
652
        assert_eq!(
653
            error.kind,
654
            ParseErrorKind::Expecting {
655
                value: "}}".to_string()
656
            }
657
        );
658
        assert!(!error.recoverable);
659
    }
660

            
661
    #[test]
662
    fn test_any_char() {
663
        let mut reader = Reader::new("a");
664
        assert_eq!(
665
            any_char(&mut reader).unwrap(),
666
            ('a', "a".to_string(), Pos { line: 1, column: 1 })
667
        );
668
        assert_eq!(reader.cursor().index, CharPos(1));
669

            
670
        let mut reader = Reader::new(" ");
671
        assert_eq!(
672
            any_char(&mut reader).unwrap(),
673
            (' ', " ".to_string(), Pos { line: 1, column: 1 })
674
        );
675
        assert_eq!(reader.cursor().index, CharPos(1));
676

            
677
        let mut reader = Reader::new("\\u0020 ");
678
        assert_eq!(
679
            any_char(&mut reader).unwrap(),
680
            (' ', "\\u0020".to_string(), Pos { line: 1, column: 1 })
681
        );
682
        assert_eq!(reader.cursor().index, CharPos(6));
683

            
684
        let mut reader = Reader::new("\\t");
685
        assert_eq!(
686
            any_char(&mut reader).unwrap(),
687
            ('\t', "\\t".to_string(), Pos { line: 1, column: 1 })
688
        );
689
        assert_eq!(reader.cursor().index, CharPos(2));
690

            
691
        let mut reader = Reader::new("#");
692
        assert_eq!(
693
            any_char(&mut reader).unwrap(),
694
            ('#', "#".to_string(), Pos { line: 1, column: 1 })
695
        );
696
        assert_eq!(reader.cursor().index, CharPos(1));
697
    }
698

            
699
    #[test]
700
    fn test_any_char_error() {
701
        let mut reader = Reader::new("");
702
        let error = any_char(&mut reader).err().unwrap();
703
        assert_eq!(error.pos, Pos { line: 1, column: 1 });
704
        assert!(error.recoverable);
705

            
706
        let mut reader = Reader::new("\t");
707
        let error = any_char(&mut reader).err().unwrap();
708
        assert_eq!(error.pos, Pos { line: 1, column: 1 });
709
        assert!(error.recoverable);
710
    }
711

            
712
    #[test]
713
    fn test_escape_char() {
714
        let mut reader = Reader::new("\\n");
715
        assert_eq!(escape_char(&mut reader).unwrap(), '\n');
716
        assert_eq!(reader.cursor().index, CharPos(2));
717

            
718
        let mut reader = Reader::new("\\u000a");
719
        assert_eq!(escape_char(&mut reader).unwrap(), '\n');
720
        assert_eq!(reader.cursor().index, CharPos(6));
721

            
722
        let mut reader = Reader::new("x");
723
        let error = escape_char(&mut reader).err().unwrap();
724
        assert_eq!(error.pos, Pos { line: 1, column: 1 });
725
        assert_eq!(
726
            error.kind,
727
            ParseErrorKind::Expecting {
728
                value: "\\".to_string()
729
            }
730
        );
731
        assert!(error.recoverable);
732
        assert_eq!(reader.cursor().index, CharPos(0));
733
    }
734

            
735
    #[test]
736
    fn test_unicode() {
737
        let mut reader = Reader::new("000a");
738
        assert_eq!(unicode(&mut reader).unwrap(), '\n');
739
        assert_eq!(reader.cursor().index, CharPos(4));
740

            
741
        let mut reader = Reader::new("c350");
742
        assert_eq!(unicode(&mut reader).unwrap(), '썐');
743
        assert_eq!(reader.cursor().index, CharPos(4));
744

            
745
        let mut reader = Reader::new("d83c\\udf78");
746
        assert_eq!(unicode(&mut reader).unwrap(), '🍸');
747
        assert_eq!(reader.cursor().index, CharPos(10));
748

            
749
        let mut reader = Reader::new("d800");
750
        let error = unicode(&mut reader).unwrap_err();
751
        assert_eq!(error.pos, Pos { line: 1, column: 5 });
752
        assert_eq!(
753
            error.kind,
754
            ParseErrorKind::Expecting {
755
                value: "\\u".to_string()
756
            }
757
        );
758
        assert!(!error.recoverable);
759

            
760
        let mut reader = Reader::new("d800\\ud800");
761
        let error = unicode(&mut reader).unwrap_err();
762
        assert_eq!(error.pos, Pos { line: 1, column: 7 });
763
        assert_eq!(error.kind, ParseErrorKind::Unicode);
764
        assert!(!error.recoverable);
765
    }
766

            
767
    #[test]
768
    fn test_hex_value() {
769
        let mut reader = Reader::new("0020x");
770
        assert_eq!(hex_value(&mut reader).unwrap(), 32);
771

            
772
        let mut reader = Reader::new("d800");
773
        assert_eq!(hex_value(&mut reader).unwrap(), 55296);
774

            
775
        let mut reader = Reader::new("x");
776
        let error = hex_value(&mut reader).unwrap_err();
777
        assert_eq!(error.pos, Pos { line: 1, column: 1 });
778
        assert_eq!(error.kind, ParseErrorKind::HexDigit);
779
        assert!(!error.recoverable);
780
    }
781

            
782
    #[test]
783
    fn test_number_value() {
784
        let mut reader = Reader::new("100");
785
        assert_eq!(
786
            number_value(&mut reader).unwrap(),
787
            JsonValue::Number("100".to_string())
788
        );
789
        assert_eq!(reader.cursor().index, CharPos(3));
790

            
791
        let mut reader = Reader::new("1.333");
792
        assert_eq!(
793
            number_value(&mut reader).unwrap(),
794
            JsonValue::Number("1.333".to_string())
795
        );
796
        assert_eq!(reader.cursor().index, CharPos(5));
797

            
798
        let mut reader = Reader::new("-1");
799
        assert_eq!(
800
            number_value(&mut reader).unwrap(),
801
            JsonValue::Number("-1".to_string())
802
        );
803
        assert_eq!(reader.cursor().index, CharPos(2));
804

            
805
        let mut reader = Reader::new("00");
806
        assert_eq!(
807
            number_value(&mut reader).unwrap(),
808
            JsonValue::Number("0".to_string())
809
        );
810
        assert_eq!(reader.cursor().index, CharPos(1));
811

            
812
        let mut reader = Reader::new("1e0");
813
        assert_eq!(
814
            number_value(&mut reader).unwrap(),
815
            JsonValue::Number("1e0".to_string())
816
        );
817
        assert_eq!(reader.cursor().index, CharPos(3));
818

            
819
        let mut reader = Reader::new("1e005");
820
        assert_eq!(
821
            number_value(&mut reader).unwrap(),
822
            JsonValue::Number("1e005".to_string())
823
        );
824
        assert_eq!(reader.cursor().index, CharPos(5));
825

            
826
        let mut reader = Reader::new("1e-005");
827
        assert_eq!(
828
            number_value(&mut reader).unwrap(),
829
            JsonValue::Number("1e-005".to_string())
830
        );
831
        assert_eq!(reader.cursor().index, CharPos(6));
832
    }
833

            
834
    #[test]
835
    fn test_number_value_error() {
836
        let mut reader = Reader::new("true");
837
        let error = number_value(&mut reader).err().unwrap();
838
        assert_eq!(error.pos, Pos { line: 1, column: 1 });
839
        assert_eq!(
840
            error.kind,
841
            ParseErrorKind::Expecting {
842
                value: "number".to_string()
843
            }
844
        );
845
        assert!(error.recoverable);
846

            
847
        let mut reader = Reader::new("1.x");
848
        let error = number_value(&mut reader).err().unwrap();
849
        assert_eq!(error.pos, Pos { line: 1, column: 3 });
850
        assert_eq!(
851
            error.kind,
852
            ParseErrorKind::Expecting {
853
                value: "digits".to_string()
854
            }
855
        );
856
        assert!(!error.recoverable);
857
    }
858

            
859
    #[test]
860
    fn test_expression_value() {
861
        let mut reader = Reader::new("{{n}}");
862
        assert_eq!(
863
            expression_value(&mut reader).unwrap(),
864
            JsonValue::Placeholder(Placeholder {
865
                space0: Whitespace {
866
                    value: String::new(),
867
                    source_info: SourceInfo::new(Pos::new(1, 3), Pos::new(1, 3))
868
                },
869
                expr: Expr {
870
                    kind: ExprKind::Variable(Variable {
871
                        name: "n".to_string(),
872
                        source_info: SourceInfo::new(Pos::new(1, 3), Pos::new(1, 4))
873
                    }),
874
                    source_info: SourceInfo::new(Pos::new(1, 3), Pos::new(1, 4))
875
                },
876
                space1: Whitespace {
877
                    value: String::new(),
878
                    source_info: SourceInfo::new(Pos::new(1, 4), Pos::new(1, 4))
879
                }
880
            })
881
        );
882
        assert_eq!(reader.cursor().index, CharPos(5));
883
    }
884

            
885
    #[test]
886
    fn test_list_value() {
887
        let mut reader = Reader::new("[]");
888
        assert_eq!(
889
            list_value(&mut reader, 0).unwrap(),
890
            JsonValue::List {
891
                space0: String::new(),
892
                elements: vec![]
893
            }
894
        );
895
        assert_eq!(reader.cursor().index, CharPos(2));
896

            
897
        let mut reader = Reader::new("[ ]");
898
        assert_eq!(
899
            list_value(&mut reader, 0).unwrap(),
900
            JsonValue::List {
901
                space0: " ".to_string(),
902
                elements: vec![]
903
            }
904
        );
905
        assert_eq!(reader.cursor().index, CharPos(3));
906

            
907
        let mut reader = Reader::new("[true, false]");
908
        assert_eq!(
909
            list_value(&mut reader, 0).unwrap(),
910
            JsonValue::List {
911
                space0: String::new(),
912
                elements: vec![
913
                    JsonListElement {
914
                        space0: String::new(),
915
                        value: JsonValue::Boolean(true),
916
                        space1: String::new(),
917
                    },
918
                    JsonListElement {
919
                        space0: String::from(" "),
920
                        value: JsonValue::Boolean(false),
921
                        space1: String::new(),
922
                    }
923
                ],
924
            }
925
        );
926
        assert_eq!(reader.cursor().index, CharPos(13));
927
    }
928

            
929
    #[test]
930
    fn test_list_error() {
931
        let mut reader = Reader::new("true");
932
        let error = list_value(&mut reader, 0).err().unwrap();
933
        assert_eq!(error.pos, Pos { line: 1, column: 1 });
934
        assert_eq!(
935
            error.kind,
936
            ParseErrorKind::Expecting {
937
                value: "[".to_string()
938
            }
939
        );
940
        assert!(error.recoverable);
941

            
942
        let mut reader = Reader::new("[1, 2,]");
943
        let error = list_value(&mut reader, 0).err().unwrap();
944
        assert_eq!(error.pos, Pos { line: 1, column: 6 });
945
        assert_eq!(
946
            error.kind,
947
            ParseErrorKind::Json(JsonErrorVariant::TrailingComma),
948
        );
949
        assert!(!error.recoverable);
950
    }
951

            
952
    #[test]
953
    fn test_list_element() {
954
        let mut reader = Reader::new("true");
955
        assert_eq!(
956
            list_element(&mut reader, 1).unwrap(),
957
            JsonListElement {
958
                space0: String::new(),
959
                value: JsonValue::Boolean(true),
960
                space1: String::new(),
961
            }
962
        );
963
        assert_eq!(reader.cursor().index, CharPos(4));
964
    }
965

            
966
    #[test]
967
    fn test_object_value() {
968
        let mut reader = Reader::new("{}");
969
        assert_eq!(
970
            object_value(&mut reader, 0).unwrap(),
971
            JsonValue::Object {
972
                space0: String::new(),
973
                elements: vec![]
974
            }
975
        );
976
        assert_eq!(reader.cursor().index, CharPos(2));
977

            
978
        let mut reader = Reader::new("{ }");
979
        assert_eq!(
980
            object_value(&mut reader, 0).unwrap(),
981
            JsonValue::Object {
982
                space0: " ".to_string(),
983
                elements: vec![]
984
            }
985
        );
986
        assert_eq!(reader.cursor().index, CharPos(3));
987

            
988
        let mut reader = Reader::new("{\n  \"a\": true\n}");
989
        assert_eq!(
990
            object_value(&mut reader, 0).unwrap(),
991
            JsonValue::Object {
992
                space0: "\n  ".to_string(),
993
                elements: vec![JsonObjectElement {
994
                    space0: String::new(),
995
                    name: Template::new(
996
                        Some('"'),
997
                        vec![TemplateElement::String {
998
                            value: "a".to_string(),
999
                            source: "a".to_source()
                        }],
                        SourceInfo::new(Pos::new(2, 4), Pos::new(2, 5))
                    ),
                    space1: String::new(),
                    space2: " ".to_string(),
                    value: JsonValue::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::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));
    }
}