1
/*
2
 * Hurl (https://hurl.dev)
3
 * Copyright (C) 2025 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::{choice, non_recover, ParseError as ParseErrorTrait};
21
use crate::parser::primitives::{boolean, hex_digit, literal, try_literal};
22
use crate::parser::template::EncodedString;
23
use crate::parser::{templatize, JsonErrorVariant, ParseError, ParseErrorKind, ParseResult};
24
use crate::reader::{Pos, Reader};
25

            
26
29850
pub fn parse(reader: &mut Reader) -> ParseResult<JsonValue> {
27
29850
    choice(
28
29850
        &[
29
29850
            null_value,
30
29850
            boolean_value,
31
29850
            string_value,
32
29850
            number_value,
33
29850
            expression_value,
34
29850
            list_value,
35
29850
            object_value,
36
29850
        ],
37
29850
        reader,
38
    )
39
}
40

            
41
/// Helper for parse, but already knowing that we are inside a JSON body.
42
3390
fn parse_in_json(reader: &mut Reader) -> ParseResult<JsonValue> {
43
3390
    if let Some(c) = reader.peek() {
44
3390
        if c == ',' {
45
            let kind = ParseErrorKind::Json(JsonErrorVariant::EmptyElement);
46
            return Err(ParseError::new(reader.cursor().pos, false, kind));
47
        }
48
    }
49
3390
    match parse(reader) {
50
3350
        Ok(r) => Ok(r),
51
        // The only error that is recoverable is caused by reaching object_value try_literal('{'),
52
        // but this is not recoverable in this case, because we already know that we are in a JSON
53
        // body. So, we change the error to CannotResolve for the object found.
54
40
        Err(e) => match e {
55
            ParseError {
56
                recoverable: true, ..
57
            } => {
58
15
                let kind = ParseErrorKind::Json(JsonErrorVariant::ExpectingElement);
59
15
                Err(ParseError::new(e.pos, false, kind))
60
            }
61
25
            _ => Err(ParseError::new(e.pos, false, e.kind)),
62
        },
63
    }
64
}
65

            
66
29870
pub fn null_value(reader: &mut Reader) -> ParseResult<JsonValue> {
67
29870
    try_literal("null", reader)?;
68
45
    Ok(JsonValue::Null)
69
}
70

            
71
29835
pub fn boolean_value(reader: &mut Reader) -> ParseResult<JsonValue> {
72
29835
    let value = boolean(reader)?;
73
85
    Ok(JsonValue::Boolean(value))
74
}
75

            
76
29730
fn string_value(reader: &mut Reader) -> ParseResult<JsonValue> {
77
29730
    let template = string_template(reader)?;
78
1300
    Ok(JsonValue::String(template))
79
}
80

            
81
31955
fn string_template(reader: &mut Reader) -> ParseResult<Template> {
82
31955
    try_literal("\"", reader)?;
83
3535
    let delimiter = Some('"');
84
3535
    let mut chars = vec![];
85
3535
    let start = reader.cursor();
86
    loop {
87
33500
        if reader.peek() == Some('"') || reader.is_eof() {
88
3525
            break;
89
        }
90
29975
        let char = any_char(reader)?;
91
29965
        chars.push(char);
92
    }
93
3525
    let end = reader.cursor();
94

            
95
3525
    let encoded_string = EncodedString {
96
3525
        source_info: SourceInfo::new(start.pos, end.pos),
97
3525
        chars,
98
3525
    };
99
3525
    literal("\"", reader)?;
100
3525
    let elements = templatize(encoded_string)?;
101

            
102
3525
    let template = Template::new(delimiter, elements, SourceInfo::new(start.pos, end.pos));
103
3525
    Ok(template)
104
}
105

            
106
29975
fn any_char(reader: &mut Reader) -> ParseResult<(char, String, Pos)> {
107
29975
    let start = reader.cursor();
108
29975
    match escape_char(reader) {
109
375
        Ok(c) => Ok((c, reader.read_from(start.index), start.pos)),
110
29600
        Err(e) => {
111
29600
            if e.recoverable {
112
29590
                reader.seek(start);
113
29590
                match reader.read() {
114
                    None => {
115
                        let kind = ParseErrorKind::Expecting {
116
                            value: "char".to_string(),
117
                        };
118
                        Err(ParseError::new(start.pos, true, kind))
119
                    }
120
29590
                    Some(c) => {
121
29590
                        if ['\\', '\x08', '\n', '\x0c', '\r', '\t'].contains(&c) {
122
                            let kind = ParseErrorKind::Expecting {
123
                                value: "char".to_string(),
124
                            };
125
                            Err(ParseError::new(start.pos, true, kind))
126
                        } else {
127
29590
                            Ok((c, reader.read_from(start.index), start.pos))
128
                        }
129
                    }
130
                }
131
            } else {
132
10
                Err(e)
133
            }
134
        }
135
    }
136
}
137

            
138
29975
fn escape_char(reader: &mut Reader) -> ParseResult<char> {
139
29975
    try_literal("\\", reader)?;
140
385
    let start = reader.cursor();
141
385
    match reader.read() {
142
200
        Some('"') => Ok('"'),
143
5
        Some('\\') => Ok('\\'),
144
        Some('/') => Ok('/'),
145
        Some('b') => Ok('\x08'),
146
165
        Some('n') => Ok('\n'),
147
        Some('f') => Ok('\x0c'),
148
        Some('r') => Ok('\r'),
149
        Some('t') => Ok('\t'),
150
15
        Some('u') => unicode(reader),
151
        _ => Err(ParseError::new(
152
            start.pos,
153
            false,
154
            ParseErrorKind::EscapeChar,
155
        )),
156
    }
157
}
158

            
159
15
fn unicode(reader: &mut Reader) -> ParseResult<char> {
160
15
    let start = reader.cursor();
161
15
    let cp1 = hex_value(reader)?;
162
10
    let cp = if is_surrogate(cp1) {
163
10
        literal("\\u", reader)?;
164
10
        let start = reader.cursor();
165
10
        let cp2 = hex_value(reader)?;
166
10
        match cp_surrogate_pair(cp1, cp2) {
167
5
            None => return Err(ParseError::new(start.pos, false, ParseErrorKind::Unicode)),
168
5
            Some(cp) => cp,
169
        }
170
    } else {
171
        cp1
172
    };
173
5
    let c = match char::from_u32(cp) {
174
        None => return Err(ParseError::new(start.pos, false, ParseErrorKind::Unicode)),
175
5
        Some(c) => c,
176
    };
177
5
    Ok(c)
178
}
179

            
180
// 0xd800-0xdc00 encodes the high 10 bits of a pair.
181
// 0xdc00-0xe000 encodes the low 10 bits of a pair.
182
// the value is those 20 bits plus 0x10000.
183
const SURR1: u32 = 0xd800;
184
const SURR2: u32 = 0xdc00;
185
const SURR3: u32 = 0xe000;
186
const SURR_SELF: u32 = 0x10000;
187

            
188
/// Returns whether the specified Unicode code point can appear in a surrogate pair.
189
10
fn is_surrogate(cp: u32) -> bool {
190
10
    (SURR1..SURR3).contains(&cp)
191
}
192

            
193
10
fn cp_surrogate_pair(cp1: u32, cp2: u32) -> Option<u32> {
194
10
    if (SURR1..SURR2).contains(&cp1) && (SURR2..SURR3).contains(&cp2) {
195
5
        Some(((cp1 - SURR1) << 10) | ((cp2 - SURR2) + SURR_SELF))
196
    } else {
197
5
        None
198
    }
199
}
200

            
201
25
fn hex_value(reader: &mut Reader) -> ParseResult<u32> {
202
25
    let digit1 = non_recover(hex_digit, reader)?;
203
25
    let digit2 = non_recover(hex_digit, reader)?;
204
25
    let digit3 = non_recover(hex_digit, reader)?;
205
25
    let digit4 = non_recover(hex_digit, reader)?;
206
20
    let value = digit1 * (16 * 16 * 16) + digit2 * (16 * 16) + digit3 * 16 + digit4;
207
20
    Ok(value)
208
}
209

            
210
28460
pub fn number_value(reader: &mut Reader) -> ParseResult<JsonValue> {
211
28460
    let sign = match try_literal("-", reader) {
212
28415
        Err(_) => String::new(),
213
45
        Ok(_) => "-".to_string(),
214
    };
215
28460
    let int = integer(reader)?;
216
1150
    let frac = fraction(reader)?;
217
1150
    let exp = exponent(reader)?;
218
1150
    Ok(JsonValue::Number(format!("{sign}{int}{frac}{exp}")))
219
}
220

            
221
28460
fn integer(reader: &mut Reader) -> ParseResult<String> {
222
28460
    let start = reader.cursor();
223
28460
    match try_literal("0", reader) {
224
        Err(_) => {
225
33668
            let digits = reader.read_while(|c| c.is_ascii_digit());
226
28210
            if digits.is_empty() {
227
27310
                let kind = ParseErrorKind::Expecting {
228
27310
                    value: "number".to_string(),
229
27310
                };
230
27310
                Err(ParseError::new(start.pos, true, kind))
231
            } else {
232
900
                Ok(digits)
233
            }
234
        }
235
250
        Ok(_) => Ok("0".to_string()),
236
    }
237
}
238

            
239
1150
fn fraction(reader: &mut Reader) -> ParseResult<String> {
240
1150
    match try_literal(".", reader) {
241
        Ok(_) => {
242
4363
            let digits = reader.read_while(|c| c.is_ascii_digit());
243
665
            if digits.is_empty() {
244
                let kind = ParseErrorKind::Expecting {
245
                    value: "digits".to_string(),
246
                };
247
                Err(ParseError::new(reader.cursor().pos, false, kind))
248
            } else {
249
665
                Ok(format!(".{digits}"))
250
            }
251
        }
252
485
        Err(_) => Ok(String::new()),
253
    }
254
}
255

            
256
1150
fn exponent(reader: &mut Reader) -> ParseResult<String> {
257
1150
    if reader.peek() == Some('e') || reader.peek() == Some('E') {
258
5
        reader.read();
259
5
        let exponent_sign = match try_literal("-", reader) {
260
            Ok(_) => "-".to_string(),
261
5
            Err(_) => match try_literal("+", reader) {
262
                Ok(_) => "+".to_string(),
263
5
                Err(_) => String::new(),
264
            },
265
        };
266
21
        let exponent_digits = reader.read_while(|c| c.is_ascii_digit());
267
5
        Ok(format!("e{exponent_sign}{exponent_digits}"))
268
    } else {
269
1145
        Ok(String::new())
270
    }
271
}
272

            
273
27285
fn expression_value(reader: &mut Reader) -> ParseResult<JsonValue> {
274
27285
    let exp = placeholder::parse(reader)?;
275
60
    Ok(JsonValue::Placeholder(exp))
276
}
277

            
278
27225
fn list_value(reader: &mut Reader) -> ParseResult<JsonValue> {
279
27225
    try_literal("[", reader)?;
280
410
    let space0 = whitespace(reader);
281
410
    let mut elements = vec![];
282

            
283
    // at least one element
284
410
    if reader.peek() != Some(']') {
285
365
        let first_element = list_element(reader)?;
286
365
        elements.push(first_element);
287

            
288
        loop {
289
1165
            if reader.peek() == Some(']') {
290
355
                break;
291
            }
292
            // Reports "expecting ']'" in case the user forgot to add the last ']', e.g
293
            // `[1, 2`
294
810
            if reader.peek() != Some(',') {
295
                break;
296
            }
297
            // The reader advances after literal(","), so this saves its position to report an
298
            // error in case it happens.
299
810
            let save = reader.cursor();
300
810
            literal(",", reader)?;
301
            // If there is one more comma, e.g. [1, 2,], it's better to report to the user because
302
            // this occurrence is common.
303
2542
            if reader.peek_if(|c| !is_whitespace(c)) == Some(']') {
304
5
                let kind = ParseErrorKind::Json(JsonErrorVariant::TrailingComma);
305
5
                return Err(ParseError::new(save.pos, false, kind));
306
            }
307
805
            let element = list_element(reader)?;
308
800
            elements.push(element);
309
        }
310
    }
311
400
    literal("]", reader)?;
312

            
313
400
    Ok(JsonValue::List { space0, elements })
314
}
315

            
316
1170
fn list_element(reader: &mut Reader) -> ParseResult<JsonListElement> {
317
1170
    let space0 = whitespace(reader);
318
1170
    let value = parse_in_json(reader)?;
319
1165
    let space1 = whitespace(reader);
320
1165
    Ok(JsonListElement {
321
1165
        space0,
322
1165
        value,
323
1165
        space1,
324
1165
    })
325
}
326

            
327
26875
pub fn object_value(reader: &mut Reader) -> ParseResult<JsonValue> {
328
26875
    try_literal("{", reader)?;
329
815
    let space0 = whitespace(reader);
330
815
    let mut elements = vec![];
331
815
    if reader.peek() != Some('}') {
332
775
        let first_element = object_element(reader)?;
333
735
        elements.push(first_element);
334

            
335
        loop {
336
2185
            if reader.peek() == Some('}') {
337
730
                break;
338
            }
339
            // Reports "expecting '}'" in case the user forgot to add the last '}', e.g
340
            // `{"name": "abc"`
341
1455
            if reader.peek() != Some(',') {
342
                break;
343
            }
344
            // The reader advances after literal(","), so this saves its position to report an
345
            // error in case it happens.
346
1455
            let save = reader.cursor();
347
1455
            literal(",", reader)?;
348
            // If there is one more comma, e.g. {"a": "b",}, it's better to report to the user
349
            // because this occurrence is common.
350
8631
            if reader.peek_if(|c| !is_whitespace(c)) == Some('}') {
351
5
                let kind = ParseErrorKind::Json(JsonErrorVariant::TrailingComma);
352
5
                return Err(ParseError::new(save.pos, false, kind));
353
            }
354
1450
            let element = object_element(reader)?;
355
1450
            elements.push(element);
356
        }
357
    }
358

            
359
    // at least one element
360

            
361
770
    literal("}", reader)?;
362

            
363
770
    Ok(JsonValue::Object { space0, elements })
364
}
365

            
366
2225
fn key(reader: &mut Reader) -> ParseResult<Template> {
367
2225
    let name = string_template(reader).map_err(|e| e.to_non_recoverable())?;
368
2225
    Ok(name)
369
}
370

            
371
2225
fn object_element(reader: &mut Reader) -> ParseResult<JsonObjectElement> {
372
2225
    let space0 = whitespace(reader);
373
    //literal("\"", reader)?;
374
2225
    let name = key(reader)?;
375
    //literal("\"", reader)?;
376
2225
    let space1 = whitespace(reader);
377
2225
    literal(":", reader)?;
378
2225
    let save = reader.cursor();
379
2225
    let space2 = whitespace(reader);
380
    // Checks if there is no element after ':'. In this case, a special error must be reported
381
    // because this is a common occurrence.
382
2225
    let next_char = reader.peek();
383
    // Comparing to None because `next_char` can be EOF.
384
2225
    if next_char == Some('}') || next_char.is_none() {
385
5
        let kind = ParseErrorKind::Json(JsonErrorVariant::EmptyElement);
386
5
        return Err(ParseError::new(save.pos, false, kind));
387
    }
388
2220
    let value = parse_in_json(reader)?;
389
2185
    let space3 = whitespace(reader);
390
2185
    Ok(JsonObjectElement {
391
2185
        space0,
392
2185
        name,
393
2185
        space1,
394
2185
        space2,
395
2185
        value,
396
2185
        space3,
397
2185
    })
398
}
399

            
400
41300
fn is_whitespace(c: char) -> bool {
401
41300
    c == ' ' || c == '\t' || c == '\n' || c == '\r'
402
}
403

            
404
12420
fn whitespace(reader: &mut Reader) -> String {
405
12420
    reader.read_while(is_whitespace)
406
}
407

            
408
#[cfg(test)]
409
mod tests {
410
    use super::*;
411
    use crate::ast::*;
412
    use crate::reader::CharPos;
413
    use crate::typing::ToSource;
414

            
415
    #[test]
416
    fn test_parse_error() {
417
        let mut reader = Reader::new("{ \"a\":\n}");
418
        let error = parse(&mut reader).err().unwrap();
419
        assert_eq!(error.pos, Pos { line: 1, column: 7 });
420
        assert_eq!(
421
            error.kind,
422
            ParseErrorKind::Json(JsonErrorVariant::EmptyElement)
423
        );
424
        assert!(!error.recoverable);
425

            
426
        let mut reader = Reader::new("[0,1,]");
427
        let error = parse(&mut reader).err().unwrap();
428
        assert_eq!(error.pos, Pos { line: 1, column: 5 });
429
        assert_eq!(
430
            error.kind,
431
            ParseErrorKind::Json(JsonErrorVariant::TrailingComma),
432
        );
433
        assert!(!error.recoverable);
434
    }
435

            
436
    #[test]
437
    fn test_null_value() {
438
        let mut reader = Reader::new("null");
439
        assert_eq!(null_value(&mut reader).unwrap(), JsonValue::Null);
440
        assert_eq!(reader.cursor().index, CharPos(4));
441

            
442
        let mut reader = Reader::new("true");
443
        let error = null_value(&mut reader).err().unwrap();
444
        assert_eq!(error.pos, Pos { line: 1, column: 1 });
445
        assert_eq!(
446
            error.kind,
447
            ParseErrorKind::Expecting {
448
                value: "null".to_string()
449
            }
450
        );
451
        assert!(error.recoverable);
452
    }
453

            
454
    #[test]
455
    fn test_integer() {
456
        let mut reader = Reader::new("0");
457
        assert_eq!(integer(&mut reader).unwrap(), "0".to_string());
458
        assert_eq!(reader.cursor().index, CharPos(1));
459

            
460
        let mut reader = Reader::new("123");
461
        assert_eq!(integer(&mut reader).unwrap(), "123".to_string());
462
        assert_eq!(reader.cursor().index, CharPos(3));
463

            
464
        let mut reader = Reader::new("0123");
465
        assert_eq!(integer(&mut reader).unwrap(), "0".to_string());
466
        assert_eq!(reader.cursor().index, CharPos(1));
467
    }
468

            
469
    #[test]
470
    fn test_fraction() {
471
        let mut reader = Reader::new(".5");
472
        assert_eq!(fraction(&mut reader).unwrap(), ".5".to_string());
473
        assert_eq!(reader.cursor().index, CharPos(2));
474
    }
475

            
476
    #[test]
477
    fn test_exponent() {
478
        let mut reader = Reader::new("e2");
479
        assert_eq!(exponent(&mut reader).unwrap(), "e2".to_string());
480
        assert_eq!(reader.cursor().index, CharPos(2));
481
    }
482

            
483
    #[test]
484
    fn test_boolean_value() {
485
        let mut reader = Reader::new("true");
486
        assert_eq!(
487
            boolean_value(&mut reader).unwrap(),
488
            JsonValue::Boolean(true)
489
        );
490
        assert_eq!(reader.cursor().index, CharPos(4));
491

            
492
        let mut reader = Reader::new("1");
493
        let error = boolean_value(&mut reader).err().unwrap();
494
        assert_eq!(error.pos, Pos { line: 1, column: 1 });
495
        assert_eq!(
496
            error.kind,
497
            ParseErrorKind::Expecting {
498
                value: "true|false".to_string()
499
            }
500
        );
501
        assert!(error.recoverable);
502
    }
503

            
504
    pub fn json_hello_world_value() -> JsonValue {
505
        // "hello\u0020{{name}}!"
506
        JsonValue::String(Template::new(
507
            Some('"'),
508
            vec![
509
                TemplateElement::String {
510
                    value: "Hello ".to_string(),
511
                    source: "Hello\\u0020".to_source(),
512
                },
513
                TemplateElement::Placeholder(Placeholder {
514
                    space0: Whitespace {
515
                        value: String::new(),
516
                        source_info: SourceInfo::new(Pos::new(1, 15), Pos::new(1, 15)),
517
                    },
518
                    expr: Expr {
519
                        kind: ExprKind::Variable(Variable {
520
                            name: "name".to_string(),
521
                            source_info: SourceInfo::new(Pos::new(1, 15), Pos::new(1, 19)),
522
                        }),
523
                        source_info: SourceInfo::new(Pos::new(1, 15), Pos::new(1, 19)),
524
                    },
525
                    space1: Whitespace {
526
                        value: String::new(),
527
                        source_info: SourceInfo::new(Pos::new(1, 19), Pos::new(1, 19)),
528
                    },
529
                }),
530
                TemplateElement::String {
531
                    value: "!".to_string(),
532
                    source: "!".to_source(),
533
                },
534
            ],
535
            SourceInfo::new(Pos::new(1, 2), Pos::new(1, 22)),
536
        ))
537
    }
538

            
539
    #[test]
540
    fn test_string_value() {
541
        let mut reader = Reader::new("\"\"");
542
        assert_eq!(
543
            string_value(&mut reader).unwrap(),
544
            JsonValue::String(Template::new(
545
                Some('"'),
546
                vec![],
547
                SourceInfo::new(Pos::new(1, 2), Pos::new(1, 2)),
548
            ))
549
        );
550
        assert_eq!(reader.cursor().index, CharPos(2));
551

            
552
        let mut reader = Reader::new("\"Hello\\u0020{{name}}!\"");
553
        assert_eq!(string_value(&mut reader).unwrap(), json_hello_world_value());
554
        assert_eq!(reader.cursor().index, CharPos(22));
555

            
556
        let mut reader = Reader::new("\"{}\"");
557
        assert_eq!(
558
            string_value(&mut reader).unwrap(),
559
            JsonValue::String(Template::new(
560
                Some('"'),
561
                vec![TemplateElement::String {
562
                    value: "{}".to_string(),
563
                    source: "{}".to_source(),
564
                }],
565
                SourceInfo::new(Pos::new(1, 2), Pos::new(1, 4)),
566
            ))
567
        );
568
        assert_eq!(reader.cursor().index, CharPos(4));
569
    }
570

            
571
    #[test]
572
    fn test_string_value_error() {
573
        let mut reader = Reader::new("1");
574
        let error = string_value(&mut reader).err().unwrap();
575
        assert_eq!(error.pos, Pos { line: 1, column: 1 });
576
        assert_eq!(
577
            error.kind,
578
            ParseErrorKind::Expecting {
579
                value: "\"".to_string()
580
            }
581
        );
582
        assert!(error.recoverable);
583

            
584
        let mut reader = Reader::new("\"1");
585
        let error = string_value(&mut reader).err().unwrap();
586
        assert_eq!(error.pos, Pos { line: 1, column: 3 });
587
        assert_eq!(
588
            error.kind,
589
            ParseErrorKind::Expecting {
590
                value: "\"".to_string()
591
            }
592
        );
593
        assert!(!error.recoverable);
594

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

            
607
    #[test]
608
    fn test_any_char() {
609
        let mut reader = Reader::new("a");
610
        assert_eq!(
611
            any_char(&mut reader).unwrap(),
612
            ('a', "a".to_string(), Pos { line: 1, column: 1 })
613
        );
614
        assert_eq!(reader.cursor().index, CharPos(1));
615

            
616
        let mut reader = Reader::new(" ");
617
        assert_eq!(
618
            any_char(&mut reader).unwrap(),
619
            (' ', " ".to_string(), Pos { line: 1, column: 1 })
620
        );
621
        assert_eq!(reader.cursor().index, CharPos(1));
622

            
623
        let mut reader = Reader::new("\\u0020 ");
624
        assert_eq!(
625
            any_char(&mut reader).unwrap(),
626
            (' ', "\\u0020".to_string(), Pos { line: 1, column: 1 })
627
        );
628
        assert_eq!(reader.cursor().index, CharPos(6));
629

            
630
        let mut reader = Reader::new("\\t");
631
        assert_eq!(
632
            any_char(&mut reader).unwrap(),
633
            ('\t', "\\t".to_string(), Pos { line: 1, column: 1 })
634
        );
635
        assert_eq!(reader.cursor().index, CharPos(2));
636

            
637
        let mut reader = Reader::new("#");
638
        assert_eq!(
639
            any_char(&mut reader).unwrap(),
640
            ('#', "#".to_string(), Pos { line: 1, column: 1 })
641
        );
642
        assert_eq!(reader.cursor().index, CharPos(1));
643
    }
644

            
645
    #[test]
646
    fn test_any_char_error() {
647
        let mut reader = Reader::new("");
648
        let error = any_char(&mut reader).err().unwrap();
649
        assert_eq!(error.pos, Pos { line: 1, column: 1 });
650
        assert!(error.recoverable);
651

            
652
        let mut reader = Reader::new("\t");
653
        let error = any_char(&mut reader).err().unwrap();
654
        assert_eq!(error.pos, Pos { line: 1, column: 1 });
655
        assert!(error.recoverable);
656
    }
657

            
658
    #[test]
659
    fn test_escape_char() {
660
        let mut reader = Reader::new("\\n");
661
        assert_eq!(escape_char(&mut reader).unwrap(), '\n');
662
        assert_eq!(reader.cursor().index, CharPos(2));
663

            
664
        let mut reader = Reader::new("\\u000a");
665
        assert_eq!(escape_char(&mut reader).unwrap(), '\n');
666
        assert_eq!(reader.cursor().index, CharPos(6));
667

            
668
        let mut reader = Reader::new("x");
669
        let error = escape_char(&mut reader).err().unwrap();
670
        assert_eq!(error.pos, Pos { line: 1, column: 1 });
671
        assert_eq!(
672
            error.kind,
673
            ParseErrorKind::Expecting {
674
                value: "\\".to_string()
675
            }
676
        );
677
        assert!(error.recoverable);
678
        assert_eq!(reader.cursor().index, CharPos(0));
679
    }
680

            
681
    #[test]
682
    fn test_unicode() {
683
        let mut reader = Reader::new("000a");
684
        assert_eq!(unicode(&mut reader).unwrap(), '\n');
685
        assert_eq!(reader.cursor().index, CharPos(4));
686

            
687
        let mut reader = Reader::new("c350");
688
        assert_eq!(unicode(&mut reader).unwrap(), '썐');
689
        assert_eq!(reader.cursor().index, CharPos(4));
690

            
691
        let mut reader = Reader::new("d83c\\udf78");
692
        assert_eq!(unicode(&mut reader).unwrap(), '🍸');
693
        assert_eq!(reader.cursor().index, CharPos(10));
694

            
695
        let mut reader = Reader::new("d800");
696
        let error = unicode(&mut reader).unwrap_err();
697
        assert_eq!(error.pos, Pos { line: 1, column: 5 });
698
        assert_eq!(
699
            error.kind,
700
            ParseErrorKind::Expecting {
701
                value: "\\u".to_string()
702
            }
703
        );
704
        assert!(!error.recoverable);
705

            
706
        let mut reader = Reader::new("d800\\ud800");
707
        let error = unicode(&mut reader).unwrap_err();
708
        assert_eq!(error.pos, Pos { line: 1, column: 7 });
709
        assert_eq!(error.kind, ParseErrorKind::Unicode);
710
        assert!(!error.recoverable);
711
    }
712

            
713
    #[test]
714
    fn test_hex_value() {
715
        let mut reader = Reader::new("0020x");
716
        assert_eq!(hex_value(&mut reader).unwrap(), 32);
717

            
718
        let mut reader = Reader::new("d800");
719
        assert_eq!(hex_value(&mut reader).unwrap(), 55296);
720

            
721
        let mut reader = Reader::new("x");
722
        let error = hex_value(&mut reader).unwrap_err();
723
        assert_eq!(error.pos, Pos { line: 1, column: 1 });
724
        assert_eq!(error.kind, ParseErrorKind::HexDigit);
725
        assert!(!error.recoverable);
726
    }
727

            
728
    #[test]
729
    fn test_number_value() {
730
        let mut reader = Reader::new("100");
731
        assert_eq!(
732
            number_value(&mut reader).unwrap(),
733
            JsonValue::Number("100".to_string())
734
        );
735
        assert_eq!(reader.cursor().index, CharPos(3));
736

            
737
        let mut reader = Reader::new("1.333");
738
        assert_eq!(
739
            number_value(&mut reader).unwrap(),
740
            JsonValue::Number("1.333".to_string())
741
        );
742
        assert_eq!(reader.cursor().index, CharPos(5));
743

            
744
        let mut reader = Reader::new("-1");
745
        assert_eq!(
746
            number_value(&mut reader).unwrap(),
747
            JsonValue::Number("-1".to_string())
748
        );
749
        assert_eq!(reader.cursor().index, CharPos(2));
750

            
751
        let mut reader = Reader::new("00");
752
        assert_eq!(
753
            number_value(&mut reader).unwrap(),
754
            JsonValue::Number("0".to_string())
755
        );
756
        assert_eq!(reader.cursor().index, CharPos(1));
757

            
758
        let mut reader = Reader::new("1e0");
759
        assert_eq!(
760
            number_value(&mut reader).unwrap(),
761
            JsonValue::Number("1e0".to_string())
762
        );
763
        assert_eq!(reader.cursor().index, CharPos(3));
764

            
765
        let mut reader = Reader::new("1e005");
766
        assert_eq!(
767
            number_value(&mut reader).unwrap(),
768
            JsonValue::Number("1e005".to_string())
769
        );
770
        assert_eq!(reader.cursor().index, CharPos(5));
771

            
772
        let mut reader = Reader::new("1e-005");
773
        assert_eq!(
774
            number_value(&mut reader).unwrap(),
775
            JsonValue::Number("1e-005".to_string())
776
        );
777
        assert_eq!(reader.cursor().index, CharPos(6));
778
    }
779

            
780
    #[test]
781
    fn test_number_value_error() {
782
        let mut reader = Reader::new("true");
783
        let error = number_value(&mut reader).err().unwrap();
784
        assert_eq!(error.pos, Pos { line: 1, column: 1 });
785
        assert_eq!(
786
            error.kind,
787
            ParseErrorKind::Expecting {
788
                value: "number".to_string()
789
            }
790
        );
791
        assert!(error.recoverable);
792

            
793
        let mut reader = Reader::new("1.x");
794
        let error = number_value(&mut reader).err().unwrap();
795
        assert_eq!(error.pos, Pos { line: 1, column: 3 });
796
        assert_eq!(
797
            error.kind,
798
            ParseErrorKind::Expecting {
799
                value: "digits".to_string()
800
            }
801
        );
802
        assert!(!error.recoverable);
803
    }
804

            
805
    #[test]
806
    fn test_expression_value() {
807
        let mut reader = Reader::new("{{n}}");
808
        assert_eq!(
809
            expression_value(&mut reader).unwrap(),
810
            JsonValue::Placeholder(Placeholder {
811
                space0: Whitespace {
812
                    value: String::new(),
813
                    source_info: SourceInfo::new(Pos::new(1, 3), Pos::new(1, 3))
814
                },
815
                expr: Expr {
816
                    kind: ExprKind::Variable(Variable {
817
                        name: "n".to_string(),
818
                        source_info: SourceInfo::new(Pos::new(1, 3), Pos::new(1, 4))
819
                    }),
820
                    source_info: SourceInfo::new(Pos::new(1, 3), Pos::new(1, 4))
821
                },
822
                space1: Whitespace {
823
                    value: String::new(),
824
                    source_info: SourceInfo::new(Pos::new(1, 4), Pos::new(1, 4))
825
                }
826
            })
827
        );
828
        assert_eq!(reader.cursor().index, CharPos(5));
829
    }
830

            
831
    #[test]
832
    fn test_list_value() {
833
        let mut reader = Reader::new("[]");
834
        assert_eq!(
835
            list_value(&mut reader).unwrap(),
836
            JsonValue::List {
837
                space0: String::new(),
838
                elements: vec![]
839
            }
840
        );
841
        assert_eq!(reader.cursor().index, CharPos(2));
842

            
843
        let mut reader = Reader::new("[ ]");
844
        assert_eq!(
845
            list_value(&mut reader).unwrap(),
846
            JsonValue::List {
847
                space0: " ".to_string(),
848
                elements: vec![]
849
            }
850
        );
851
        assert_eq!(reader.cursor().index, CharPos(3));
852

            
853
        let mut reader = Reader::new("[true, false]");
854
        assert_eq!(
855
            list_value(&mut reader).unwrap(),
856
            JsonValue::List {
857
                space0: String::new(),
858
                elements: vec![
859
                    JsonListElement {
860
                        space0: String::new(),
861
                        value: JsonValue::Boolean(true),
862
                        space1: String::new(),
863
                    },
864
                    JsonListElement {
865
                        space0: String::from(" "),
866
                        value: JsonValue::Boolean(false),
867
                        space1: String::new(),
868
                    }
869
                ],
870
            }
871
        );
872
        assert_eq!(reader.cursor().index, CharPos(13));
873
    }
874

            
875
    #[test]
876
    fn test_list_error() {
877
        let mut reader = Reader::new("true");
878
        let error = list_value(&mut reader).err().unwrap();
879
        assert_eq!(error.pos, Pos { line: 1, column: 1 });
880
        assert_eq!(
881
            error.kind,
882
            ParseErrorKind::Expecting {
883
                value: "[".to_string()
884
            }
885
        );
886
        assert!(error.recoverable);
887

            
888
        let mut reader = Reader::new("[1, 2,]");
889
        let error = list_value(&mut reader).err().unwrap();
890
        assert_eq!(error.pos, Pos { line: 1, column: 6 });
891
        assert_eq!(
892
            error.kind,
893
            ParseErrorKind::Json(JsonErrorVariant::TrailingComma),
894
        );
895
        assert!(!error.recoverable);
896
    }
897

            
898
    #[test]
899
    fn test_list_element() {
900
        let mut reader = Reader::new("true");
901
        assert_eq!(
902
            list_element(&mut reader).unwrap(),
903
            JsonListElement {
904
                space0: String::new(),
905
                value: JsonValue::Boolean(true),
906
                space1: String::new(),
907
            }
908
        );
909
        assert_eq!(reader.cursor().index, CharPos(4));
910
    }
911

            
912
    #[test]
913
    fn test_object_value() {
914
        let mut reader = Reader::new("{}");
915
        assert_eq!(
916
            object_value(&mut reader).unwrap(),
917
            JsonValue::Object {
918
                space0: String::new(),
919
                elements: vec![]
920
            }
921
        );
922
        assert_eq!(reader.cursor().index, CharPos(2));
923

            
924
        let mut reader = Reader::new("{ }");
925
        assert_eq!(
926
            object_value(&mut reader).unwrap(),
927
            JsonValue::Object {
928
                space0: " ".to_string(),
929
                elements: vec![]
930
            }
931
        );
932
        assert_eq!(reader.cursor().index, CharPos(3));
933

            
934
        let mut reader = Reader::new("{\n  \"a\": true\n}");
935
        assert_eq!(
936
            object_value(&mut reader).unwrap(),
937
            JsonValue::Object {
938
                space0: "\n  ".to_string(),
939
                elements: vec![JsonObjectElement {
940
                    space0: String::new(),
941
                    name: Template::new(
942
                        Some('"'),
943
                        vec![TemplateElement::String {
944
                            value: "a".to_string(),
945
                            source: "a".to_source()
946
                        }],
947
                        SourceInfo::new(Pos::new(2, 4), Pos::new(2, 5))
948
                    ),
949
                    space1: String::new(),
950
                    space2: " ".to_string(),
951
                    value: JsonValue::Boolean(true),
952
                    space3: "\n".to_string(),
953
                }],
954
            }
955
        );
956
        assert_eq!(reader.cursor().index, CharPos(15));
957

            
958
        let mut reader = Reader::new("true");
959
        let error = object_value(&mut reader).err().unwrap();
960
        assert_eq!(error.pos, Pos { line: 1, column: 1 });
961
        assert_eq!(
962
            error.kind,
963
            ParseErrorKind::Expecting {
964
                value: "{".to_string()
965
            }
966
        );
967
        assert!(error.recoverable);
968
    }
969

            
970
    #[test]
971
    fn test_object_error() {
972
        let mut reader = Reader::new("{ \"a\":\n}");
973
        let error = object_value(&mut reader).err().unwrap();
974
        assert_eq!(error.pos, Pos { line: 1, column: 7 });
975
        assert_eq!(
976
            error.kind,
977
            ParseErrorKind::Json(JsonErrorVariant::EmptyElement)
978
        );
979
        assert!(!error.recoverable);
980
    }
981

            
982
    #[test]
983
    fn test_object_element() {
984
        let mut reader = Reader::new("\"a\": true");
985
        assert_eq!(
986
            object_element(&mut reader).unwrap(),
987
            JsonObjectElement {
988
                space0: String::new(),
989
                name: Template::new(
990
                    Some('"'),
991
                    vec![TemplateElement::String {
992
                        value: "a".to_string(),
993
                        source: "a".to_source()
994
                    }],
995
                    SourceInfo::new(Pos::new(1, 2), Pos::new(1, 3))
996
                ),
997
                space1: String::new(),
998
                space2: " ".to_string(),
999
                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).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).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));
    }
}