1
#[cfg(feature = "alloc")]
2
use alloc::vec::Vec;
3
use core::iter::Cloned;
4
use core::marker::PhantomData;
5
use core::slice;
6

            
7
use crate::parser::{JsonKind, ParseConfig, ParseDelegate, Parser};
8
#[cfg(feature = "alloc")]
9
use crate::{value::Entry, Object, Value};
10
use crate::{Error, ErrorKind, JsonNumber, JsonString};
11

            
12
/// A parsed JSON payload.
13
///
14
/// This type is a read-only view into the JSON payload.
15
///
16
/// This structure is faster to parse than [`Value`], but it is more work to
17
/// interact with because the entire payload is stored in a single list
18
/// internally.
19
///
20
/// The list of [`Node`]s is sequentially ordered by the order in which they
21
/// appear in the document. This means that the first [`Node`] tells us what the
22
/// root type of the document is.
23
///
24
/// The nodes [`Node::Null`], [`Node::Boolean`], [`Node::String`], and
25
/// [`Node::Number`] all directly represent a [`Value`] with the same name.
26
///
27
/// [`Node::Object`] contains a length field, which lets us know how many
28
/// key-value pairs will appear after the object's node. Object keys are
29
/// guaranteed to be [`Node::String`]s, but object values can be any [`Node`]
30
/// variant. This means care must be taken to handle nested structures.
31
///
32
/// [`Node::Array`] also contains a length field, which lets us know how many
33
/// values follow the array's node. Because array values can be any type, care
34
/// must be taken to handle nested structures correctly.
35
///
36
/// [`DocumentIter`] has multiple methods to help efficiently deal with nested
37
/// data types:
38
///
39
/// - [`skip_next_value()`](DocumentIter::skip_next_value): Skips over the next
40
///   value, taking care to handle nested structures properly.
41
/// - [`next_value()`](DocumentIter::next_value): Returns a [`Value`] from the
42
///   iterator.
43
#[derive(Debug, Eq, PartialEq)]
44
pub struct GenericDocument<'a, Backing> {
45
    nodes: Nodes<'a, Backing>,
46
}
47

            
48
impl<'a, Backing> GenericDocument<'a, Backing>
49
where
50
    Backing: NodeCollection<'a>,
51
{
52
    /// Parses a JSON payload from `source`.
53
    ///
54
    /// This function verifies that `json` is valid UTF-8 while parsing the
55
    /// JSON.
56
61
    pub fn from_json_bytes(source: &'a [u8]) -> Result<Self, Error>
57
61
    where
58
61
        Backing: Default,
59
61
    {
60
61
        let mut nodes = Nodes::default();
61
61
        Parser::parse_json_bytes(source, &mut nodes).map_err(Error::into_infallable)?;
62
61
        Ok(Self { nodes })
63
61
    }
64

            
65
    /// Parses a JSON payload from `source`, with the settings from `config`.
66
    ///
67
    /// This function verifies that `json` is valid UTF-8 while parsing the
68
    /// JSON.
69
36
    pub fn from_json_bytes_with_config(source: &'a [u8], config: ParseConfig) -> Result<Self, Error>
70
36
    where
71
36
        Backing: Default,
72
36
    {
73
36
        let mut nodes = Nodes::default();
74
36
        Parser::parse_json_bytes_with_config(source, config, &mut nodes)
75
36
            .map_err(Error::into_infallable)?;
76
3
        Ok(Self { nodes })
77
36
    }
78

            
79
    /// Parses a JSON payload from `source`.
80
    ///
81
    /// Because the `str` type guarantees that `json` is valid UTF-8, no
82
    /// additional unicode checks are performed on unescaped unicode sequences.
83
5
    pub fn from_json(source: &'a str) -> Result<Self, Error>
84
5
    where
85
5
        Backing: Default,
86
5
    {
87
5
        let mut nodes = Nodes::default();
88
5
        Parser::parse_json(source, &mut nodes).map_err(Error::into_infallable)?;
89
4
        Ok(Self { nodes })
90
5
    }
91

            
92
    /// Parses a JSON payload from `source`, with the settings from `config`.
93
    ///
94
    /// Because the `str` type guarantees that `json` is valid UTF-8, no
95
    /// additional unicode checks are performed on unescaped unicode sequences.
96
40
    pub fn from_json_with_config(source: &'a str, config: ParseConfig) -> Result<Self, Error>
97
40
    where
98
40
        Backing: Default,
99
40
    {
100
40
        let mut nodes = Nodes::default();
101
40
        Parser::parse_json_with_config(source, config, &mut nodes)
102
40
            .map_err(Error::into_infallable)?;
103
3
        Ok(Self { nodes })
104
40
    }
105

            
106
    /// Returns an iterator over the nodes in this document.
107
    #[must_use]
108
3
    pub fn iter(&self) -> DocumentIter<'_, 'a> {
109
3
        self.into_iter()
110
3
    }
111
}
112

            
113
#[cfg(feature = "alloc")]
114
impl<'a, Backing> From<GenericDocument<'a, Backing>> for Value<'a>
115
where
116
    Backing: NodeCollection<'a>,
117
{
118
59
    fn from(doc: GenericDocument<'a, Backing>) -> Self {
119
59
        let mut nodes = doc.nodes.collection.into_iter();
120
59
        let root = nodes.next().expect("empty document is invalid");
121
59
        hydrate_value_from_node(root, &mut nodes)
122
59
    }
123
}
124

            
125
#[cfg(feature = "alloc")]
126
113
fn hydrate_value_from_node<'a, I>(node: Node<'a>, remaining_nodes: &mut I) -> Value<'a>
127
113
where
128
113
    I: Iterator<Item = Node<'a>>,
129
113
{
130
113
    match node {
131
7
        Node::Null => Value::Null,
132
15
        Node::Boolean(value) => Value::Boolean(value),
133
10
        Node::String(value) => Value::String(value),
134
37
        Node::Number(number) => Value::Number(number),
135
12
        Node::Object { length: len } => {
136
12
            let mut obj = Object::with_capacity(len);
137
12
            for _ in 0..len {
138
18
                let node = remaining_nodes.next().expect("obbject missing value");
139
18
                let Node::String(key) = node else { unreachable!("object key must be string") };
140
18
                let node = remaining_nodes.next().expect("object missing value");
141
18
                obj.push(Entry {
142
18
                    key,
143
18
                    value: hydrate_value_from_node(node, remaining_nodes),
144
18
                });
145
            }
146
12
            Value::Object(obj)
147
        }
148
32
        Node::Array { length: len } => {
149
32
            let mut values = Vec::with_capacity(len);
150
35
            for _ in 0..len {
151
35
                let node = remaining_nodes.next().expect("array missing value");
152
35
                values.push(hydrate_value_from_node(node, remaining_nodes));
153
35
            }
154
32
            Value::Array(values)
155
        }
156
    }
157
113
}
158

            
159
impl<'doc, 'a, Backing> IntoIterator for &'doc GenericDocument<'a, Backing>
160
where
161
    Backing: NodeCollection<'a>,
162
{
163
    type IntoIter = DocumentIter<'doc, 'a>;
164
    type Item = Node<'a>;
165

            
166
4
    fn into_iter(self) -> Self::IntoIter {
167
4
        DocumentIter {
168
4
            nodes: self.nodes.collection.as_ref().iter().cloned(),
169
4
        }
170
4
    }
171
}
172

            
173
/// A single value in a [`Document`].
174
54
#[derive(Debug, Eq, PartialEq, Clone)]
175
pub enum Node<'a> {
176
    /// A null value.
177
    Null,
178
    /// A boolean value.
179
    Boolean(bool),
180
    /// A string value.
181
    String(JsonString<'a>),
182
    /// A numerical value.
183
    Number(JsonNumber<'a>),
184
    /// An object value with `len` key-value pairs following it.
185
    Object {
186
        /// The number of key-value pairs that this object contains.
187
        length: usize,
188
    },
189
    /// An array with `len` values following it.
190
    Array {
191
        /// The number of values that this array contains.
192
        length: usize,
193
    },
194
}
195

            
196
142
#[derive(Default, Debug, Eq, PartialEq)]
197
struct Nodes<'a, Backing> {
198
    collection: Backing,
199
    _phantom: PhantomData<&'a ()>,
200
}
201

            
202
impl<'a, Backing> Nodes<'a, Backing>
203
where
204
    Backing: NodeCollection<'a>,
205
{
206
638
    fn push_node(&mut self, node: Node<'a>) -> Result<usize, ErrorKind> {
207
638
        let index = self.collection.as_ref().len();
208
638
        self.collection.push(node)?;
209
637
        Ok(index)
210
638
    }
211

            
212
16
    pub fn push_null(&mut self) -> Result<usize, ErrorKind> {
213
16
        self.push_node(Node::Null)
214
16
    }
215

            
216
38
    pub fn push_bool(&mut self, boolean: bool) -> Result<usize, ErrorKind> {
217
38
        self.push_node(Node::Boolean(boolean))
218
38
    }
219

            
220
241
    pub fn push_string(&mut self, string: JsonString<'a>) -> Result<usize, ErrorKind> {
221
241
        self.push_node(Node::String(string))
222
241
    }
223

            
224
123
    pub fn push_number(&mut self, number: JsonNumber<'a>) -> Result<usize, ErrorKind> {
225
123
        self.push_node(Node::Number(number))
226
123
    }
227

            
228
55
    pub fn push_object(&mut self) -> Result<usize, ErrorKind> {
229
55
        self.push_node(Node::Object { length: 0 })
230
55
    }
231

            
232
165
    pub fn push_array(&mut self) -> Result<usize, ErrorKind> {
233
165
        self.push_node(Node::Array { length: 0 })
234
165
    }
235

            
236
147
    pub fn extend_object(&mut self, index: usize) {
237
147
        let Node::Object { length: len } = &mut self.collection.as_mut()[index] else { unreachable!("extended wrong type") };
238
147
        *len += 1;
239
147
    }
240

            
241
173
    pub fn extend_array(&mut self, index: usize) {
242
173
        let Node::Array { length: len } = &mut self.collection.as_mut()[index] else { unreachable!("extended wrong type") };
243
173
        *len += 1;
244
173
    }
245
}
246

            
247
impl<'a, 'b, Backing> ParseDelegate<'a> for &'b mut Nodes<'a, Backing>
248
where
249
    Backing: NodeCollection<'a>,
250
{
251
    type Array = usize;
252
    type Error = ErrorKind;
253
    type Key = ();
254
    type Object = usize;
255
    type Value = usize;
256

            
257
    #[inline]
258
16
    fn null(&mut self) -> Result<Self::Value, Self::Error> {
259
16
        self.push_null()
260
16
    }
261

            
262
    #[inline]
263
38
    fn boolean(&mut self, value: bool) -> Result<Self::Value, Self::Error> {
264
38
        self.push_bool(value)
265
38
    }
266

            
267
    #[inline]
268
123
    fn number(&mut self, value: JsonNumber<'a>) -> Result<Self::Value, Self::Error> {
269
123
        self.push_number(value)
270
123
    }
271

            
272
    #[inline]
273
94
    fn string(&mut self, value: JsonString<'a>) -> Result<Self::Value, Self::Error> {
274
94
        self.push_string(value)
275
94
    }
276

            
277
    #[inline]
278
55
    fn begin_object(&mut self) -> Result<Self::Object, Self::Error> {
279
55
        self.push_object()
280
55
    }
281

            
282
    #[inline]
283
147
    fn object_key(
284
147
        &mut self,
285
147
        object: &mut Self::Object,
286
147
        key: JsonString<'a>,
287
147
    ) -> Result<Self::Key, Self::Error> {
288
147
        self.extend_object(*object);
289
147
        self.push_string(key)?;
290
147
        Ok(())
291
147
    }
292

            
293
    #[inline]
294
139
    fn object_value(
295
139
        &mut self,
296
139
        _object: &mut Self::Object,
297
139
        _key: Self::Key,
298
139
        _value: Self::Value,
299
139
    ) -> Result<(), Self::Error> {
300
139
        Ok(())
301
139
    }
302

            
303
    #[inline]
304
11
    fn object_is_empty(&self, object: &Self::Object) -> bool {
305
11
        let Node::Object { length: len } = &self.collection.as_ref()[*object] else { unreachable!("invalid object") };
306
11
        *len == 0
307
11
    }
308

            
309
    #[inline]
310
35
    fn end_object(&mut self, object: Self::Object) -> Result<Self::Value, Self::Error> {
311
35
        Ok(object)
312
35
    }
313

            
314
    #[inline]
315
165
    fn begin_array(&mut self) -> Result<Self::Array, Self::Error> {
316
165
        self.push_array()
317
165
    }
318

            
319
    #[inline]
320
173
    fn array_value(
321
173
        &mut self,
322
173
        array: &mut Self::Array,
323
173
        _value: Self::Value,
324
173
    ) -> Result<(), Self::Error> {
325
173
        self.extend_array(*array);
326
173
        Ok(())
327
173
    }
328

            
329
    #[inline]
330
10
    fn array_is_empty(&self, array: &Self::Array) -> bool {
331
10
        let Node::Array { length: len } = &self.collection.as_ref()[*array] else { unreachable!("invalid array") };
332
10
        *len == 0
333
10
    }
334

            
335
    #[inline]
336
90
    fn end_array(&mut self, array: Self::Array) -> Result<Self::Value, Self::Error> {
337
90
        Ok(array)
338
90
    }
339

            
340
    #[inline]
341
18
    fn kind_of(&self, value: &Self::Value) -> JsonKind {
342
18
        match &self.collection.as_ref()[*value] {
343
1
            Node::Null => JsonKind::Null,
344
1
            Node::Boolean(_) => JsonKind::Boolean,
345
3
            Node::String(_) => JsonKind::String,
346
1
            Node::Number(_) => JsonKind::Number,
347
4
            Node::Object { .. } => JsonKind::Object,
348
8
            Node::Array { .. } => JsonKind::Array,
349
        }
350
18
    }
351
}
352

            
353
/// An iterator over the [`Node`]s in a [`Document`].
354
#[derive(Debug, Clone)]
355
pub struct DocumentIter<'doc, 'a> {
356
    nodes: Cloned<slice::Iter<'doc, Node<'a>>>,
357
}
358

            
359
impl<'doc, 'a> DocumentIter<'doc, 'a> {
360
    /// Reads a [`Value`] from the iterator, if any nodes remain.
361
    ///
362
    /// This function automatically reads nested objects and arrays.
363
    ///
364
    /// ```rust
365
    /// use justjson::doc::{Document, Node};
366
    /// use justjson::Value;
367
    ///
368
    /// let doc = Document::from_json(
369
    ///     r#"{
370
    ///         "a": [1, 2, 3, 4]
371
    ///     }"#,
372
    /// )
373
    /// .unwrap();
374
    ///
375
    /// let mut nodes = doc.iter();
376
    /// assert_eq!(nodes.next(), Some(Node::Object { length: 1 }));
377
    /// let Node::String(key) = nodes.next().unwrap() else { unreachable!() };
378
    /// assert_eq!(key, "a");
379
    /// let Value::Array(array) = nodes.next_value().unwrap() else { unreachable!() };
380
    /// assert_eq!(array.len(), 4);
381
    /// assert!(nodes.next().is_none());
382
    /// ```
383
    #[cfg(feature = "alloc")]
384
1
    pub fn next_value(&mut self) -> Option<Value<'a>> {
385
1
        let node = self.nodes.next()?;
386

            
387
1
        Some(hydrate_value_from_node(node, &mut self.nodes))
388
1
    }
389

            
390
    /// Skips a [`Value`], including any nested values.
391
    pub fn skip_next_value(&mut self) {
392
12
        if let Some(node) = self.nodes.next() {
393
12
            match node {
394
9
                Node::Null | Node::Boolean(_) | Node::String(_) | Node::Number(_) => {}
395
2
                Node::Object { length: len } => {
396
5
                    for _ in 0..len {
397
5
                        // Skip the key
398
5
                        self.skip_next_value();
399
5
                        // Skip the value
400
5
                        self.skip_next_value();
401
5
                    }
402
                }
403
1
                Node::Array { length: len } => {
404
1
                    for _ in 0..len {
405
1
                        // Skip the value
406
1
                        self.skip_next_value();
407
1
                    }
408
                }
409
            }
410
        }
411
12
    }
412
}
413

            
414
impl<'doc, 'a> Iterator for DocumentIter<'doc, 'a> {
415
    type Item = Node<'a>;
416

            
417
    #[inline]
418
17
    fn next(&mut self) -> Option<Self::Item> {
419
17
        self.nodes.next()
420
17
    }
421
}
422

            
423
1
#[test]
424
#[cfg(feature = "alloc")]
425
1
fn document_iteration() {
426
1
    let source = r#"{"a":1,"b":true,"c":"hello","d":[null],"e":{}}"#;
427
1
    let doc = Document::from_json(source).unwrap();
428
1
    assert_eq!(
429
1
        doc.iter().collect::<Vec<_>>(),
430
1
        alloc::vec![
431
1
            Node::Object { length: 5 },
432
1
            Node::String(JsonString::from_json("\"a\"").unwrap()),
433
1
            Node::Number(JsonNumber::from_json("1").unwrap()),
434
1
            Node::String(JsonString::from_json("\"b\"").unwrap()),
435
1
            Node::Boolean(true),
436
1
            Node::String(JsonString::from_json("\"c\"").unwrap()),
437
1
            Node::String(JsonString::from_json("\"hello\"").unwrap()),
438
1
            Node::String(JsonString::from_json("\"d\"").unwrap()),
439
1
            Node::Array { length: 1 },
440
1
            Node::Null,
441
1
            Node::String(JsonString::from_json("\"e\"").unwrap()),
442
1
            Node::Object { length: 0 },
443
1
        ]
444
1
    );
445
1
    let value = doc.iter().next_value().unwrap();
446
1
    assert_eq!(value, Value::from_json(source).unwrap());
447

            
448
    // Test skipping
449
1
    let mut iter = doc.iter();
450
1
    iter.skip_next_value();
451
1
    assert!(iter.next().is_none());
452
1
}
453

            
454
/// A collection for use with [`GenericDocument`].
455
pub trait NodeCollection<'a>:
456
    AsRef<[Node<'a>]> + AsMut<[Node<'a>]> + IntoIterator<Item = Node<'a>>
457
{
458
    /// Push `node` to the end of the collection.
459
    fn push(&mut self, node: Node<'a>) -> Result<(), ErrorKind>;
460
}
461

            
462
#[cfg(feature = "alloc")]
463
impl<'a> NodeCollection<'a> for Vec<Node<'a>> {
464
    #[inline]
465
631
    fn push(&mut self, node: Node<'a>) -> Result<(), ErrorKind> {
466
631
        self.push(node);
467
631
        Ok(())
468
631
    }
469
}
470

            
471
#[cfg(feature = "heapless")]
472
impl<'a, const N: usize> NodeCollection<'a> for heapless::Vec<Node<'a>, N> {
473
    #[inline]
474
7
    fn push(&mut self, node: Node<'a>) -> Result<(), ErrorKind> {
475
7
        self.push(node).map_err(|_| ErrorKind::PaylodTooLarge)
476
7
    }
477
}
478

            
479
/// A convenience alias for a [`GenericDocument`] that uses a `Vec` from
480
/// `std`/`alloc`.
481
#[cfg(feature = "alloc")]
482
pub type Document<'a> = GenericDocument<'a, Vec<Node<'a>>>;
483

            
484
/// A convenience alias for a [`GenericDocument`] that uses a `heapless::Vec`.
485
#[cfg(feature = "heapless")]
486
pub type HeaplessDocument<'a, const N: usize> = GenericDocument<'a, heapless::Vec<Node<'a>, N>>;