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
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
//! Value builder traits for JSON parsing.
use crate::source::Source;
/// Trait for building JSON values during parsing.
pub trait ValueBuilder<'a, S: Source>: Sized {
/// Whether the value that it is building is lazy.
///
/// If `true` the parser won't call any of the building methods except for [`ValueBuilder::raw`] at the end of parsing.
/// This allows the parser to skip *efficiently* while also validating the JSON. As of right now, it will ignore the
/// following flags [`CUSTOM_LITERAL`](Self::CUSTOM_LITERAL), [`REJECT_CTRL_CHAR`](StringBuilder::REJECT_CTRL_CHAR)
/// and [`REJECT_INVALID_ESCAPE`](StringBuilder::REJECT_INVALID_ESCAPE). [`ValueBuilder::apply_span`] won't be called either.
///
/// Requires the source to be non volatile.
const LAZY: bool;
/// Whether the value is to parse literals by itself.
///
/// If `true` the parser will not parse the literals but will call [`ValueBuilder::literal`] to parse them.
/// This excludes string literals.
const CUSTOM_LITERAL: bool;
/// The error type used by this builder.
type Error: ErrorBuilder;
/// The array type used by this builder.
type Array: ArrayBuilder<Self> + Into<Self>;
/// The object type used by this builder.
type Object: ObjectBuilder<Self::String, Self> + Into<Self>;
/// The string type used by this builder.
type String: StringBuilder<'a, S, Self::Error> + Into<Self>;
/// Creates a value by the given byte slice.
///
/// Called when [`CUSTOM_LITERAL`](Self::CUSTOM_LITERAL) is `true`. The provided byte slice
/// contains only contiguous ASCII bytes, excluding the following:
///
/// `'{'`, `'}'`, `'['`, `']'`, `'"'`, `':'`, `','`, `'/'`, `' '`, `'\n'`, `'\t'`, `'\r'`, `'\0'`
fn literal(s: &'a [u8]) -> Result<Self, Self::Error>;
/// Creates a value by the given integer value.
fn integer(val: u64, neg: bool) -> Self;
/// Creates a value by the given floating point value.
fn float(val: f64) -> Self;
/// Creates a value by the given boolean value.
fn bool(val: bool) -> Self;
/// Creates a value in the context of null value in JSON.
fn null() -> Self;
/// Creates a value by the given raw JSON byte slice.
///
/// Only called once at the end when [`LAZY`](Self::LAZY) is `true`. All the other building methods won't be called.
fn raw(s: &'a [u8]) -> Self;
/// Applies span information. The given offsets will be byte offsets.
fn apply_span(&mut self, start: usize, end: usize);
}
/// Trait for building JSON array during parsing.
pub trait ArrayBuilder<V> {
/// Create a new array builder.
fn new() -> Self;
/// Create a new array builder with the specified capacity hint.
fn with_capacity(cap: usize) -> Self;
/// Returns the number of elements in the array.
///
/// Only called at the end of array parsing.
fn len(&self) -> usize;
/// Adds a value to the array.
fn on_value(&mut self, val: V);
/// Called when array parsing completes, e.g., for sorting.
fn on_complete(&mut self);
}
/// Trait for building JSON object during parsing.
pub trait ObjectBuilder<K, V> {
/// Create a new object builder.
fn new() -> Self;
/// Create a new object builder with the specified capacity hint.
fn with_capacity(cap: usize) -> Self;
/// Returns the number of elements in the object.
///
/// Only called at the end of object parsing.
fn len(&self) -> usize;
/// Adds a key-value to the object.
fn on_value(&mut self, key: K, val: V);
/// Called when object parsing completes, e.g., for sorting.
fn on_complete(&mut self);
}
/// Trait for building JSON string during parsing.
pub trait StringBuilder<'a, S: Source, E: ErrorBuilder> {
/// Whether to reject unescaped ascii control characters.
const REJECT_CTRL_CHAR: bool;
/// Whether to reject invalid escape sequences.
const REJECT_INVALID_ESCAPE: bool;
/// Create a new string builder.
fn new() -> Self;
/// Called when the parser encounters escape sequence. The given byte slice will be the parsed escape
/// sequence and the length will be less than or equal to 4.
fn on_escape(&mut self, s: &[u8]);
/// Called before calling [`StringBuilder::on_escape`].
///
/// This is the byte slice before escape sequence excluding `'\'` at the end.
fn on_chunk(&mut self, s: &'a [u8]);
/// Called at the final remaining byte slice.
fn on_final_chunk(&mut self, s: &'a [u8]);
/// Applies span information. The given offsets will be byte offsets.
fn apply_span(&mut self, start: usize, end: usize);
/// This function will always be called at the end of parsing string.
/// The given byte slice is the whole string excluding the surrounding quotes.
fn on_complete(&mut self, s: &'a [u8]) -> Result<(), E>;
}
/// Trait for building errors during parsing.
pub trait ErrorBuilder {
/// Unexpected EOF while parsing.
fn eof() -> Self;
/// Expected colon while parsing object.
fn expected_colon() -> Self;
/// Expected value but found EOF instead.
fn expected_value() -> Self;
/// Comma after the last element of an array or an object.
fn trailing_comma() -> Self;
/// String wasn't properly terminated.
fn unclosed_string() -> Self;
/// Invalid escape sequence in string.
fn invalid_escape() -> Self;
/// Found raw control characters inside string while parsing.
fn control_character() -> Self;
/// Invalid JSON literal.
fn invalid_literal() -> Self;
/// Number ending with a decimal point.
fn trailing_decimal() -> Self;
/// Number starting with a decimal point.
fn leading_decimal() -> Self;
/// Number starting with zero.
fn leading_zero() -> Self;
/// Number is bigger than it can represent.
fn number_overflow() -> Self;
/// Unexpected token while parsing.
fn unexpected_token() -> Self;
/// Applies span information. The given offsets will be byte offsets.
fn apply_span(&mut self, start: usize, end: usize);
}