Skip to main content

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}