1use crate::Result;
2use crate::error::Fail;
3
4pub struct Scan;
5
6impl Scan {
7 pub fn ws(input: &[u8], idx: &mut usize) {
8 while *idx < input.len() && input[*idx].is_ascii_whitespace() {
9 *idx += 1;
10 }
11 }
12
13 pub fn eat_byte(input: &[u8], idx: &mut usize, want: u8) -> bool {
14 if *idx < input.len() && input[*idx] == want {
15 *idx += 1;
16 true
17 } else {
18 false
19 }
20 }
21
22 pub fn expect_byte(input: &[u8], idx: &mut usize, want: u8) -> Result<()> {
23 if Self::eat_byte(input, idx, want) {
24 return Ok(());
25 }
26 Err(Fail::bad())
27 }
28
29 pub fn expect_prop(input: &[u8], idx: &mut usize, first: bool, want: &[u8]) -> Result<()> {
30 Self::ws(input, idx);
31 if !first {
32 Self::expect_byte(input, idx, b',')?;
33 Self::ws(input, idx);
34 }
35 Self::expect_byte(input, idx, b'"')?;
36 let end = idx.saturating_add(want.len());
37 if input.get(*idx..end) != Some(want) {
38 return Err(Fail::bad());
39 }
40 *idx = end;
41 Self::expect_byte(input, idx, b'"')?;
42 Self::ws(input, idx);
43 Self::expect_byte(input, idx, b':')?;
44 Self::ws(input, idx);
45 Ok(())
46 }
47
48 pub fn seek_name(input: &[u8], idx: &mut usize, want: &[u8]) -> Result<()> {
49 let need = want.len() + 3;
50 while idx.saturating_add(need) <= input.len() {
51 if input[*idx] == b'"' {
52 let key_start = idx.saturating_add(1);
53 let key_end = key_start.saturating_add(want.len());
54 if input.get(key_start..key_end) == Some(want)
55 && input.get(key_end) == Some(&b'"')
56 && input.get(key_end + 1) == Some(&b':')
57 {
58 *idx = key_end + 2;
59 return Ok(());
60 }
61 }
62 *idx += 1;
63 }
64 Err(Fail::bad())
65 }
66
67 pub fn eat_null(input: &[u8], idx: &mut usize) -> bool {
68 if input.get(*idx..(*idx + 4)) == Some(b"null") {
69 *idx += 4;
70 true
71 } else {
72 false
73 }
74 }
75
76 pub fn skip_plain_string(input: &[u8], idx: &mut usize) -> Result<()> {
77 Self::expect_byte(input, idx, b'"')?;
78 while *idx < input.len() {
79 match input[*idx] {
80 b'"' => {
81 *idx += 1;
82 return Ok(());
83 }
84 b'\\' => return Err(Fail::bad()),
85 _ => *idx += 1,
86 }
87 }
88 Err(Fail::bad())
89 }
90
91 pub fn skip_value(input: &[u8], idx: &mut usize) -> Result<()> {
92 Self::ws(input, idx);
93 if *idx >= input.len() {
94 return Err(Fail::bad());
95 }
96 match input[*idx] {
97 b'"' => {
98 let _ = Self::str_slice(input, idx)?;
99 Ok(())
100 }
101 b'{' => Self::skip_group(input, idx, b'{', b'}'),
102 b'[' => Self::skip_group(input, idx, b'[', b']'),
103 b't' => {
104 let _ = crate::parse::Parse::bool(input, idx)?;
105 Ok(())
106 }
107 b'f' => {
108 let _ = crate::parse::Parse::bool(input, idx)?;
109 Ok(())
110 }
111 b'n' => {
112 if input.get(*idx..(*idx + 4)) == Some(b"null") {
113 *idx += 4;
114 Ok(())
115 } else {
116 Err(Fail::bad())
117 }
118 }
119 b'-' | b'0'..=b'9' => Self::skip_number(input, idx),
120 _ => Err(Fail::bad()),
121 }
122 }
123
124 fn skip_number(input: &[u8], idx: &mut usize) -> Result<()> {
125 let start = *idx;
126 let _ = Self::eat_byte(input, idx, b'-');
127 if !Self::skip_digits(input, idx) {
128 return Err(Fail::bad());
129 }
130 if Self::eat_byte(input, idx, b'.') && !Self::skip_digits(input, idx) {
131 return Err(Fail::bad());
132 }
133 if *idx < input.len() && (input[*idx] == b'e' || input[*idx] == b'E') {
134 *idx += 1;
135 if *idx < input.len() && (input[*idx] == b'+' || input[*idx] == b'-') {
136 *idx += 1;
137 }
138 if !Self::skip_digits(input, idx) {
139 return Err(Fail::bad());
140 }
141 }
142 if *idx == start {
143 return Err(Fail::bad());
144 }
145 Ok(())
146 }
147
148 fn skip_digits(input: &[u8], idx: &mut usize) -> bool {
149 let start = *idx;
150 while *idx < input.len() && input[*idx].is_ascii_digit() {
151 *idx += 1;
152 }
153 *idx != start
154 }
155
156 pub fn str_slice<'a>(input: &'a [u8], idx: &mut usize) -> Result<&'a [u8]> {
157 Self::expect_byte(input, idx, b'"')?;
158 let start = *idx;
159 while *idx < input.len() {
160 match input[*idx] {
161 b'\\' => {
162 *idx += 2;
163 }
164 b'"' => {
165 let end = *idx;
166 *idx += 1;
167 return Ok(&input[start..end]);
168 }
169 _ => {
170 *idx += 1;
171 }
172 }
173 }
174 Err(Fail::bad())
175 }
176
177 pub(super) fn decode_str(input: &[u8]) -> Result<Vec<u8>> {
178 let mut out = Vec::with_capacity(input.len());
179 let mut idx = 0usize;
180 while idx < input.len() {
181 match input[idx] {
182 b'\\' => {
183 idx += 1;
184 if idx >= input.len() {
185 return Err(Fail::bad());
186 }
187 match input[idx] {
188 b'"' => out.push(b'"'),
189 b'\\' => out.push(b'\\'),
190 b'/' => out.push(b'/'),
191 b'b' => out.push(0x08),
192 b'f' => out.push(0x0c),
193 b'n' => out.push(b'\n'),
194 b'r' => out.push(b'\r'),
195 b't' => out.push(b'\t'),
196 _ => return Err(Fail::bad()),
197 }
198 }
199 b => out.push(b),
200 }
201 idx += 1;
202 }
203 Ok(out)
204 }
205
206 fn skip_group(input: &[u8], idx: &mut usize, open: u8, close: u8) -> Result<()> {
207 Self::expect_byte(input, idx, open)?;
208 let mut depth = 1usize;
209 while *idx < input.len() {
210 match input[*idx] {
211 b'"' => {
212 let _ = Self::str_slice(input, idx)?;
213 }
214 b if b == open => {
215 depth += 1;
216 *idx += 1;
217 }
218 b if b == close => {
219 depth -= 1;
220 *idx += 1;
221 if depth == 0 {
222 return Ok(());
223 }
224 }
225 _ => {
226 *idx += 1;
227 }
228 }
229 }
230 Err(Fail::bad())
231 }
232}