1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
|
use super::{decode_pair, Value};
use std::{collections::HashMap, convert::TryInto, str::FromStr};
grammar;
pub RawValue: Value = {
"null" => Value::Null,
"true" => Value::Bool(true),
"false" => Value::Bool(false),
Num => Value::Number(<>),
Str => Value::String(<>),
"[" <Comma<RawValue>> "]" => Value::Array(<>),
"{" <Comma<(<Str> ":" <RawValue>)>> "}" => Value::Object(<>.into_iter().collect()),
};
pub Num: f64 = r"-?(0|[1-9][0-9]*)(\.[0-9]*)([eE][-+]?[0-9]+)" => f64::from_str(<>).unwrap();
pub Str: String = r#""([^\\"]|\\.)*""# => {
let mut out = String::new();
let mut iter = <>.chars();
while let Some(c) = iter.next() {
let c = match c {
c @ '\x20'..='\x21' | c @ '\x23'..='\x5B' | c @ '\x5D'..='\u{10FFFF}' => c,
'\\' => match iter.next().unwrap() {
'\"' => '\x22',
'\\' => '\x5C',
'/' => '\x2F',
'b' => '\x08',
'f' => '\x0C',
'n' => '\x0A',
'r' => '\x0D',
't' => '\x09',
'u' => {
let v = iter.by_ref().take(4).collect::<String>();
assert_eq!(v.len(), 4);
let v = u16::from_str_radix(&v, 16).unwrap();
let codepoint = if (0xD800..=0xDFFF).contains(&v) {
let skipped = iter.by_ref().take(2).collect::<String>();
assert_eq!(skipped, "\\u");
let o = iter.by_ref().take(4).collect::<String>();
assert_eq!(o.len(), 4);
let o = u16::from_str_radix(&o, 16).unwrap();
decode_pair(v, o)
} else {
u32::from(v)
};
codepoint.try_into().unwrap()
}
_ => panic!(),
}
_ => panic!(),
};
out.push(c);
}
out
};
Comma<T>: Vec<T> = {
T? => <>.into_iter().collect(),
<v : (<T> ",")+> <e : T> => {
let mut v = v;
v.push(e);
v
}
}
|