json_cursor/cursor.rs
1//! The cursor: a position in the input, moved forward one token at a time.
2
3use alloc::string::String;
4use core::str;
5
6use crate::number::{self, Number};
7use crate::scan::Scan;
8use crate::{skip, text};
9use crate::{Error, ErrorKind};
10
11/// What kind of value is next, from its first byte.
12#[derive(Clone, Copy, Debug, PartialEq, Eq)]
13pub enum Kind {
14 /// `{`
15 Object,
16 /// `[`
17 Array,
18 /// `"`
19 String,
20 /// `-` or a digit
21 Number,
22 /// `t` or `f`
23 Bool,
24 /// `n`
25 Null,
26}
27
28/// The next value, as [`Cursor::value`] reads it.
29#[derive(Clone, Copy, Debug, PartialEq, Eq)]
30pub enum Value<'s> {
31 /// A string, borrowed from the input or decoded into the caller's buffer.
32 String(&'s str),
33 /// A number: its exact text, and its value as an `i64` or an `f64`.
34 Number(Number<'s>),
35 /// `true` or `false`.
36 Bool(bool),
37 /// `null`.
38 Null,
39 /// An array starts here: read it with [`Cursor::first_item`].
40 Array,
41 /// An object starts here: read it with [`Cursor::first_key`].
42 Object,
43}
44
45/// How deep [`Cursor::skip`] goes into arrays and objects, unless set with
46/// [`Cursor::with_depth_limit`]: serde_json's limit.
47pub const DEFAULT_DEPTH_LIMIT: usize = 128;
48
49/// A strict JSON pull cursor over text.
50///
51/// Make one from text with [`new`](Self::new), or from bytes with [`from_bytes`](Self::from_bytes),
52/// which checks their UTF-8 once, in one pass. Every key, string and number is then a slice of the
53/// text, with no further check.
54///
55/// Read the next value with [`value`](Self::value), or with the call for its kind:
56/// [`string`](Self::string), [`number`](Self::number), [`bool`](Self::bool), [`null`](Self::null), an
57/// object's keys with [`first_key`](Self::first_key) and [`next_key`](Self::next_key), an array's
58/// items with [`first_item`](Self::first_item) and [`next_item`](Self::next_item), or any value with
59/// [`skip`](Self::skip). [`peek`](Self::peek) says which kind is next. [`finish`](Self::finish)
60/// checks that nothing follows.
61///
62/// Every byte read is checked against RFC 8259, skipped values included: a call returns an
63/// [`Error`] at the first byte that is not JSON. After an error, the cursor's position is
64/// unspecified, so start again from the input.
65#[derive(Clone, Debug)]
66pub struct Cursor<'a> {
67 text: &'a str,
68 scan: Scan<'a>,
69 depth_limit: usize,
70}
71
72impl<'a> Cursor<'a> {
73 /// A cursor at the start of `text`.
74 #[inline]
75 pub fn new(text: &'a str) -> Self {
76 Cursor {
77 text,
78 scan: Scan::new(text.as_bytes()),
79 depth_limit: DEFAULT_DEPTH_LIMIT,
80 }
81 }
82
83 /// A cursor at the start of `bytes`, once they are checked as UTF-8, in one pass. `Err` with
84 /// [`ErrorKind::Utf8`] at the first byte that is not.
85 #[inline]
86 pub fn from_bytes(bytes: &'a [u8]) -> Result<Self, Error> {
87 str::from_utf8(bytes)
88 .map(Self::new)
89 .map_err(|e| Error::new(ErrorKind::Utf8, e.valid_up_to()))
90 }
91
92 /// How deep [`skip`](Self::skip) goes into arrays and objects before it returns
93 /// [`ErrorKind::TooDeep`]. The skip keeps its own stack, so no limit can overflow the call
94 /// stack. [`DEFAULT_DEPTH_LIMIT`] when not set.
95 #[inline]
96 pub fn with_depth_limit(mut self, limit: usize) -> Self {
97 self.depth_limit = limit;
98 self
99 }
100
101 /// The offset of the next byte to read.
102 #[inline]
103 pub fn position(&self) -> usize {
104 self.scan.at
105 }
106
107 /// The kind of the next value, after any whitespace. Nothing is consumed.
108 #[inline]
109 pub fn peek(&mut self) -> Result<Kind, Error> {
110 Ok(match self.scan.next_byte()? {
111 b'{' => Kind::Object,
112 b'[' => Kind::Array,
113 b'"' => Kind::String,
114 b'-' | b'0'..=b'9' => Kind::Number,
115 b't' | b'f' => Kind::Bool,
116 b'n' => Kind::Null,
117 _ => return Err(self.scan.err(ErrorKind::Expected("a value"))),
118 })
119 }
120
121 /// The next value, after any whitespace, in one look at its first byte: a string, a number, a
122 /// boolean or `null`, read; or the start of an array or an object, not consumed, to be read with
123 /// [`first_item`](Self::first_item) or [`first_key`](Self::first_key). A string is borrowed
124 /// or decoded as in [`string`](Self::string).
125 #[inline]
126 pub fn value<'s>(&mut self, buf: &'s mut String) -> Result<Value<'s>, Error>
127 where
128 'a: 's,
129 {
130 Ok(match self.scan.next_byte()? {
131 b'"' => Value::String(self.string_at(buf)?),
132 b'-' | b'0'..=b'9' => Value::Number(self.number_at()?),
133 b'{' => Value::Object,
134 b'[' => Value::Array,
135 b't' => self.scan.literal(b"true", "`true`").map(|()| Value::Bool(true))?,
136 b'f' => self.scan.literal(b"false", "`false`").map(|()| Value::Bool(false))?,
137 b'n' => self.scan.literal(b"null", "`null`").map(|()| Value::Null)?,
138 _ => return Err(self.scan.err(ErrorKind::Expected("a value"))),
139 })
140 }
141
142 /// Enters the object at the cursor and reads its first key and colon, or `None` when the object
143 /// is empty. Read the key's value next. The key is borrowed from the input when it has no
144 /// escapes, else decoded into `buf`, which it then borrows.
145 #[inline]
146 pub fn first_key<'s>(&mut self, buf: &'s mut String) -> Result<Option<&'s str>, Error>
147 where
148 'a: 's,
149 {
150 self.scan.expect(b'{', "`{`")?;
151 match self.scan.next_byte()? {
152 b'}' => {
153 self.scan.at += 1;
154 Ok(None)
155 }
156 b'"' => self.key(buf).map(Some),
157 _ => Err(self.scan.err(ErrorKind::Expected("a key or `}`"))),
158 }
159 }
160
161 /// After a value in an object: the next key and colon, or `None` at the object's end, which is
162 /// consumed. The key is borrowed as in [`first_key`](Self::first_key).
163 #[inline]
164 pub fn next_key<'s>(&mut self, buf: &'s mut String) -> Result<Option<&'s str>, Error>
165 where
166 'a: 's,
167 {
168 match self.scan.next_byte()? {
169 b',' => {
170 self.scan.at += 1;
171 match self.scan.next_byte()? {
172 b'"' => self.key(buf).map(Some),
173 _ => Err(self.scan.err(ErrorKind::Expected("a key"))),
174 }
175 }
176 b'}' => {
177 self.scan.at += 1;
178 Ok(None)
179 }
180 _ => Err(self.scan.err(ErrorKind::Expected("`,` or `}`"))),
181 }
182 }
183
184 /// Enters the array at the cursor: `true` when it has a first item, which is read next, and
185 /// `false` when it is empty.
186 #[inline]
187 pub fn first_item(&mut self) -> Result<bool, Error> {
188 self.scan.expect(b'[', "`[`")?;
189 if self.scan.next_byte()? == b']' {
190 self.scan.at += 1;
191 Ok(false)
192 } else {
193 Ok(true)
194 }
195 }
196
197 /// After an item in an array: `true` when another follows, which is read next, and `false` at
198 /// the array's end, which is consumed.
199 #[inline]
200 pub fn next_item(&mut self) -> Result<bool, Error> {
201 match self.scan.next_byte()? {
202 b',' => {
203 self.scan.at += 1;
204 Ok(true)
205 }
206 b']' => {
207 self.scan.at += 1;
208 Ok(false)
209 }
210 _ => Err(self.scan.err(ErrorKind::Expected("`,` or `]`"))),
211 }
212 }
213
214 /// The string at the cursor: borrowed from the input when it has no escapes, else decoded into
215 /// `buf`, which it then borrows.
216 #[inline]
217 pub fn string<'s>(&mut self, buf: &'s mut String) -> Result<&'s str, Error>
218 where
219 'a: 's,
220 {
221 if self.scan.next_byte()? != b'"' {
222 return Err(self.scan.err(ErrorKind::Expected("a string")));
223 }
224 self.string_at(buf)
225 }
226
227 /// The number at the cursor: its exact text, and its value as an `i64` or an `f64`. Its grammar
228 /// is checked; its size is not limited, since the text keeps every digit.
229 #[inline]
230 pub fn number(&mut self) -> Result<Number<'a>, Error> {
231 match self.scan.next_byte()? {
232 b'-' | b'0'..=b'9' => self.number_at(),
233 _ => Err(self.scan.err(ErrorKind::Expected("a number"))),
234 }
235 }
236
237 /// The `true` or `false` at the cursor.
238 #[inline]
239 pub fn bool(&mut self) -> Result<bool, Error> {
240 match self.scan.next_byte()? {
241 b't' => self.scan.literal(b"true", "`true`").map(|()| true),
242 b'f' => self.scan.literal(b"false", "`false`").map(|()| false),
243 _ => Err(self.scan.err(ErrorKind::Expected("`true` or `false`"))),
244 }
245 }
246
247 /// The `null` at the cursor.
248 #[inline]
249 pub fn null(&mut self) -> Result<(), Error> {
250 if self.scan.next_byte()? != b'n' {
251 return Err(self.scan.err(ErrorKind::Expected("`null`")));
252 }
253 self.scan.literal(b"null", "`null`")
254 }
255
256 /// Reads past the value at the cursor, of any kind, checking every byte of it: its grammar, its
257 /// strings' escapes, and its depth. Numbers are checked but not read.
258 #[inline]
259 pub fn skip(&mut self) -> Result<(), Error> {
260 skip::skip::<false>(&mut self.scan, self.depth_limit)
261 }
262
263 /// Checks that only whitespace follows.
264 #[inline]
265 pub fn finish(&mut self) -> Result<(), Error> {
266 self.scan.finish()
267 }
268
269 /// At a number's first byte: the number. Inlined, so a value is not returned through memory.
270 #[inline(always)]
271 fn number_at(&mut self) -> Result<Number<'a>, Error> {
272 let start = self.scan.at;
273 let (end, parts) = number::read::<true>(self.scan.bytes, start)?;
274 self.scan.at = end;
275 Ok(Number::new(self.text, start, end, parts))
276 }
277
278 /// At a string's opening quote: the string, borrowed or decoded into `buf`.
279 #[inline(always)]
280 fn string_at<'s>(&mut self, buf: &'s mut String) -> Result<&'s str, Error>
281 where
282 'a: 's,
283 {
284 let (end, borrowed) = text::read(self.text, self.scan.at, buf)?;
285 self.scan.at = end;
286 Ok(match borrowed {
287 Some(text) => text,
288 None => buf.as_str(),
289 })
290 }
291
292 /// At a key's opening quote: the key, then its colon.
293 #[inline]
294 fn key<'s>(&mut self, buf: &'s mut String) -> Result<&'s str, Error>
295 where
296 'a: 's,
297 {
298 let key = self.string_at(buf)?;
299 self.scan.expect(b':', "`:`")?;
300 Ok(key)
301 }
302}