1
#[cfg(feature = "alloc")]
2
use alloc::{string::String, vec::Vec};
3
use core::convert::Infallible;
4
use core::fmt::{self, Display};
5
use core::ops::{Deref, DerefMut, Index, IndexMut};
6

            
7
use crate::parser::{JsonKind, ParseConfig, ParseDelegate, Parser};
8
use crate::{Error, JsonNumber, JsonString};
9

            
10
/// A JSON value.
11
///
12
/// The `Backing` generic is the storage mechanism used by [`JsonNumber`] and
13
/// [`JsonString`]. This is generally `&str` or `Cow<str>`.
14
182
#[derive(Debug, Eq, PartialEq)]
15
pub enum Value<'a> {
16
    /// A JSON number.
17
    Number(JsonNumber<'a>),
18
    /// A JSON string.
19
    String(JsonString<'a>),
20
    /// A boolean value.
21
    Boolean(bool),
22
    /// A JSON object (key/value pairs).
23
    Object(Object<'a>),
24
    /// A JSON array (list of values).
25
    Array(Vec<Value<'a>>),
26
    /// A null value.
27
    Null,
28
}
29

            
30
impl<'a> Value<'a> {
31
    /// Parses a JSON value from `json`, returning a `Value<&str>` that borrows
32
    /// data from `json`.
33
    ///
34
    /// Because the `str` type guarantees that `json` is valid UTF-8, no
35
    /// additional unicode checks are performed on unescaped unicode sequences.
36
65
    pub fn from_json(json: &'a str) -> Result<Self, Error> {
37
65
        Self::from_json_with_config(json, ParseConfig::default())
38
65
    }
39

            
40
    /// Parses a JSON value from `json` using the settings from`config`,
41
    /// returning a `Value<&str>` that borrows data from `json`.
42
    ///
43
    /// Because the `str` type guarantees that `json` is valid UTF-8, no
44
    /// additional unicode checks are performed on unescaped unicode sequences.
45
285
    pub fn from_json_with_config(json: &'a str, config: ParseConfig) -> Result<Self, Error> {
46
285
        Parser::parse_json_with_config(json, config, ValueParser)
47
285
    }
48

            
49
    /// Parses a JSON value from `json`, returning a `Value<&str>` that borrows
50
    /// data from `json`.
51
    ///
52
    /// This function verifies that `json` is valid UTF-8 while parsing the
53
    /// JSON.
54
209
    pub fn from_json_bytes(json: &'a [u8]) -> Result<Self, Error> {
55
209
        Self::from_json_bytes_with_config(json, ParseConfig::default())
56
209
    }
57

            
58
    /// Parses a JSON value from `json` using the settings from`config`,
59
    /// returning a `Value<&str>` that borrows data from `json`.
60
    ///
61
    /// This function verifies that `json` is valid UTF-8 while parsing the
62
    /// JSON.
63
425
    pub fn from_json_bytes_with_config(json: &'a [u8], config: ParseConfig) -> Result<Self, Error> {
64
425
        Parser::parse_json_bytes_with_config(json, config, ValueParser)
65
425
    }
66

            
67
    /// Returns the [`Object`] inside of this value, if this is a
68
    /// [`Value::Object`].
69
    #[must_use]
70
    #[inline]
71
    pub const fn as_object(&self) -> Option<&Object<'a>> {
72
5
        if let Self::Object(obj) = self {
73
4
            Some(obj)
74
        } else {
75
1
            None
76
        }
77
5
    }
78

            
79
    /// Returns a mutable reference to the [`Object`] inside of this value, if
80
    /// this is a [`Value::Object`].
81
    #[must_use]
82
    #[inline]
83
    pub fn as_object_mut(&mut self) -> Option<&mut Object<'a>> {
84
5
        if let Self::Object(obj) = self {
85
4
            Some(obj)
86
        } else {
87
1
            None
88
        }
89
5
    }
90

            
91
    /// Returns the contained value associated with `key`, if this is a
92
    /// [`Value::Object`]. Returns `None` if the value is not an object or if
93
    /// the key is not found.
94
    ///
95
    /// # Performance
96
    ///
97
    /// [`Object`] uses a `Vec` of [`Entry`] types to store its entries. If the
98
    /// operation being performed can be done with a single iteration over the
99
    /// value's contents instead of multiple random accesses, the iteration
100
    /// should be preferred. Additional options to make random access faster in
101
    /// environments that can support it [are being considered][issue] for
102
    /// future releases.
103
    ///
104
    /// [issue]: https://github.com/khonsulabs/justjson/issues/7
105
    #[must_use]
106
    #[inline]
107
2
    pub fn get(&self, key: &str) -> Option<&Value<'a>> {
108
2
        let object = self.as_object()?;
109
2
        object.get(key)
110
2
    }
111

            
112
    /// Returns a mutable reference to the contained value associated with
113
    /// `key`, if this is a [`Value::Object`]. Returns `None` if the value is
114
    /// not an object or if the key is not found.
115
    ///
116
    /// # Performance
117
    ///
118
    /// [`Object`] uses a `Vec` of [`Entry`] types to store its entries. If the
119
    /// operation being performed can be done with a single iteration over the
120
    /// value's contents instead of multiple random accesses, the iteration
121
    /// should be preferred. Additional options to make random access faster in
122
    /// environments that can support it [are being considered][issue] for
123
    /// future releases.
124
    ///
125
    /// [issue]: https://github.com/khonsulabs/justjson/issues/7
126
    #[must_use]
127
    #[inline]
128
4
    pub fn get_mut(&mut self, key: &str) -> Option<&mut Value<'a>> {
129
4
        let object = self.as_object_mut()?;
130
3
        object.get_mut(key)
131
4
    }
132

            
133
    /// Returns the [`JsonString`] inside of this value, if this is a
134
    /// [`Value::String`].
135
    #[must_use]
136
    #[inline]
137
    pub const fn as_string(&self) -> Option<&JsonString<'a>> {
138
3
        if let Self::String(obj) = self {
139
2
            Some(obj)
140
        } else {
141
1
            None
142
        }
143
3
    }
144

            
145
    /// Returns a reference to the contents of this value if it is a
146
    /// [`Value::String`], and it does not have any escape sequences that need
147
    /// to be decoded.
148
    #[must_use]
149
    #[inline]
150
    pub fn as_str(&self) -> Option<&str> {
151
2
        if let Self::String(json_string) = self {
152
1
            json_string.as_str()
153
        } else {
154
1
            None
155
        }
156
2
    }
157

            
158
    /// Returns the [`JsonNumber`] inside of this value, if this is a
159
    /// [`Value::Number`].
160
    #[must_use]
161
    #[inline]
162
    pub const fn as_number(&self) -> Option<&JsonNumber<'a>> {
163
16
        if let Self::Number(obj) = self {
164
15
            Some(obj)
165
        } else {
166
1
            None
167
        }
168
16
    }
169

            
170
    /// Parses the contained value as an [`f32`], if it is a number.
171
    ///
172
    /// The JSON parser only validates that the number takes a correct form. If
173
    /// a number cannot be parsed by the underlying routine due to having too
174
    /// many digits, it this function can return None.
175
    #[must_use]
176
1
    pub fn as_f32(&self) -> Option<f32> {
177
1
        self.as_number().and_then(JsonNumber::as_f32)
178
1
    }
179

            
180
    /// Parses the contained value as an [`f64`], if it is a number.
181
    ///
182
    /// The JSON parser only validates that the number takes a correct form. If
183
    /// a number cannot be parsed by the underlying routine due to having too
184
    /// many digits, it this function can return None.
185
    #[must_use]
186
1
    pub fn as_f64(&self) -> Option<f64> {
187
1
        self.as_number().and_then(JsonNumber::as_f64)
188
1
    }
189

            
190
    /// Returns the `bool` inside of this value, if this is a
191
    /// [`Value::Boolean`].
192
    #[must_use]
193
    #[inline]
194
    pub const fn as_bool(&self) -> Option<bool> {
195
2
        if let Self::Boolean(value) = self {
196
1
            Some(*value)
197
        } else {
198
1
            None
199
        }
200
2
    }
201

            
202
    /// Returns the slice of values inside of this value, if this is a
203
    /// [`Value::Array`].
204
    #[must_use]
205
    #[inline]
206
    pub fn as_array(&self) -> Option<&[Self]> {
207
3
        if let Self::Array(value) = self {
208
2
            Some(value)
209
        } else {
210
1
            None
211
        }
212
3
    }
213

            
214
    /// Returns a mutable reference to the Vec of values inside of this value,
215
    /// if this is a [`Value::Array`].
216
    #[must_use]
217
    #[inline]
218
    pub fn as_array_mut(&mut self) -> Option<&mut Vec<Self>> {
219
2
        if let Self::Array(value) = self {
220
1
            Some(value)
221
        } else {
222
1
            None
223
        }
224
2
    }
225

            
226
    /// Returns the contained value at `index`, if this is a [`Value::Array`].
227
    /// Returns `None` if the value is not an array or if `index` is beyond the
228
    /// bounds of the array.
229
    #[must_use]
230
    #[inline]
231
1
    pub fn get_index(&self, index: usize) -> Option<&Value<'a>> {
232
1
        let sequence = self.as_array()?;
233
1
        sequence.get(index)
234
1
    }
235

            
236
    /// Returns a mutable reference to the contained value at `index`, if this
237
    /// is a [`Value::Array`]. Returns `None` if the value is not an array or if
238
    /// `index` is beyond the bounds of the array.
239
    #[must_use]
240
    #[inline]
241
2
    pub fn get_index_mut(&mut self, index: usize) -> Option<&mut Value<'a>> {
242
2
        let sequence = self.as_array_mut()?;
243
1
        sequence.get_mut(index)
244
2
    }
245

            
246
    /// Returns true if this value is `null`/[`Value::Null`].
247
    #[must_use]
248
    #[inline]
249
2
    pub const fn is_null(&self) -> bool {
250
2
        matches!(self, Value::Null)
251
2
    }
252

            
253
171
    fn write_json<W: fmt::Write, const PRETTY: bool>(
254
171
        &self,
255
171
        indentation: &str,
256
171
        line_ending: &str,
257
171
        destination: W,
258
171
    ) -> fmt::Result {
259
171
        let mut state = WriteState::<W, PRETTY>::new(destination, indentation, line_ending);
260
171

            
261
171
        self.write_json_value(&mut state)
262
171
    }
263

            
264
374
    fn write_json_value<W: fmt::Write, const PRETTY: bool>(
265
374
        &self,
266
374
        state: &mut WriteState<'_, W, PRETTY>,
267
374
    ) -> fmt::Result {
268
374
        match self {
269
28
            Value::String(string) => state.write_json(string),
270
127
            Value::Number(number) => state.write(number.source()),
271
21
            Value::Boolean(bool) => state.write(if *bool { "true" } else { "false" }),
272
12
            Value::Null => state.write("null"),
273
32
            Value::Object(obj) => Self::write_json_object(obj, state),
274
154
            Value::Array(array) => Self::write_json_array(array, state),
275
        }
276
374
    }
277

            
278
    fn write_json_object<W: fmt::Write, const PRETTY: bool>(
279
        obj: &Object<'_>,
280
        state: &mut WriteState<'_, W, PRETTY>,
281
    ) -> fmt::Result {
282
32
        state.begin_object()?;
283

            
284
32
        if !obj.0.is_empty() {
285
18
            state.new_line()?;
286
48
            for (index, entry) in obj.0.iter().enumerate() {
287
48
                state.write_json(&entry.key)?;
288
48
                state.write_object_key_end()?;
289
48
                entry.value.write_json_value(state)?;
290
48
                if index != obj.0.len() - 1 {
291
30
                    state.write(",")?;
292
18
                }
293
48
                state.new_line()?;
294
            }
295
14
        }
296

            
297
32
        state.end_object()
298
32
    }
299

            
300
    fn write_json_array<W: fmt::Write, const PRETTY: bool>(
301
        array: &Vec<Self>,
302
        state: &mut WriteState<'_, W, PRETTY>,
303
    ) -> fmt::Result {
304
154
        state.begin_array()?;
305

            
306
154
        if !array.is_empty() {
307
141
            state.new_line()?;
308
155
            for (index, value) in array.iter().enumerate() {
309
155
                value.write_json_value(state)?;
310
155
                if index != array.len() - 1 {
311
14
                    state.write(",")?;
312
141
                }
313
155
                state.new_line()?;
314
            }
315
13
        }
316

            
317
154
        state.end_array()
318
154
    }
319

            
320
    /// Converts this value to its JSON representation, with extra whitespace to
321
    /// make it easier for a human to read.
322
    ///
323
    /// This uses two spaces for indentation, and `\n` for end of lines. Use
324
    /// [`to_json_pretty_custom()`](Self::to_json_pretty_custom) to customize
325
    /// the formatting behavior.
326
    ///
327
    /// # Panics
328
    ///
329
    /// This function will panic if there is not enough memory to format the
330
    /// JSON.
331
    #[must_use]
332
2
    pub fn to_json_pretty(&self) -> String {
333
2
        let mut out = String::new();
334
2
        self.pretty_write_json_to(&mut out).expect("out of memory");
335
2
        out
336
2
    }
337

            
338
    /// Converts this value to its JSON representation, with extra whitespace to
339
    /// make it easier for a human to read.
340
    ///
341
    /// # Panics
342
    ///
343
    /// This function will panic if there is not enough memory to format the
344
    /// JSON.
345
    #[must_use]
346
1
    pub fn to_json_pretty_custom(&self, indentation: &str, line_ending: &str) -> String {
347
1
        let mut out = String::new();
348
1
        self.pretty_write_json_to_custom(indentation, line_ending, &mut out)
349
1
            .expect("out of memory");
350
1
        out
351
1
    }
352

            
353
    /// Converts this value to its JSON representation, with no extraneous
354
    /// whitespace.
355
    ///
356
    /// # Panics
357
    ///
358
    /// This function will panic if there is not enough memory to format the
359
    /// JSON.
360
    #[must_use]
361
166
    pub fn to_json(&self) -> String {
362
166
        let mut out = String::new();
363
166
        self.write_json_to(&mut out).expect("out of memory");
364
166
        out
365
166
    }
366

            
367
    /// Writes this value's JSON representation to `destination`, with no extraneous
368
    /// whitespace.
369
167
    pub fn write_json_to<W: fmt::Write>(&self, destination: W) -> fmt::Result {
370
167
        self.write_json::<W, false>("", "", destination)
371
167
    }
372

            
373
    /// Writes this value's JSON representation to `destination`, with extra
374
    /// whitespace to make it easier for a human to read.
375
    ///
376
    /// This uses two spaces for indentation, and `\n` for end of lines. Use
377
    /// [`to_json_pretty_custom()`](Self::to_json_pretty_custom) to customize
378
    /// the formatting behavior.
379
3
    pub fn pretty_write_json_to<W: fmt::Write>(&self, destination: W) -> fmt::Result {
380
3
        self.pretty_write_json_to_custom("  ", "\n", destination)
381
3
    }
382

            
383
    /// Writes this value's JSON representation to `destination`, with extra
384
    /// whitespace to make it easier for a human to read.
385
4
    pub fn pretty_write_json_to_custom<W: fmt::Write>(
386
4
        &self,
387
4
        indentation: &str,
388
4
        line_ending: &str,
389
4
        destination: W,
390
4
    ) -> fmt::Result {
391
4
        self.write_json::<W, true>(indentation, line_ending, destination)
392
4
    }
393
}
394

            
395
macro_rules! impl_as_number {
396
    ($name:ident, $type:ident) => {
397
        impl Value<'_> {
398
            /// Parses the contained value as an
399
            #[doc = concat!("[`", stringify!($type), "`]")]
400
            /// if possible.
401
            ///
402
            /// If the source number is a floating point number or has a negative sign,
403
            /// this will always return None.
404
            #[must_use]
405
12
            pub fn $name(&self) -> Option<$type> {
406
12
                self.as_number().and_then(JsonNumber::$name)
407
12
            }
408
        }
409
    };
410
}
411

            
412
impl_as_number!(as_u8, u8);
413
impl_as_number!(as_u16, u16);
414
impl_as_number!(as_u32, u32);
415
impl_as_number!(as_u64, u64);
416
impl_as_number!(as_u128, u128);
417
impl_as_number!(as_usize, usize);
418
impl_as_number!(as_i8, i8);
419
impl_as_number!(as_i16, i16);
420
impl_as_number!(as_i32, i32);
421
impl_as_number!(as_i64, i64);
422
impl_as_number!(as_i128, i128);
423
impl_as_number!(as_isize, isize);
424

            
425
1
#[test]
426
1
fn value_ases() {
427
1
    assert!(Value::from(true).as_bool().unwrap());
428
1
    assert_eq!(
429
1
        Value::String(JsonString::from_json("\"\"").unwrap())
430
1
            .as_string()
431
1
            .unwrap(),
432
1
        ""
433
1
    );
434
1
    assert_eq!(
435
1
        Value::String(JsonString::from_json("\"\"").unwrap())
436
1
            .as_str()
437
1
            .unwrap(),
438
1
        ""
439
1
    );
440
1
    assert_eq!(
441
1
        Value::Number(JsonNumber::from_json("1").unwrap())
442
1
            .as_number()
443
1
            .unwrap()
444
1
            .as_u64()
445
1
            .unwrap(),
446
1
        1
447
1
    );
448
1
    assert_eq!(
449
1
        Value::Object(Object::new()).as_object().unwrap(),
450
1
        &Object::new()
451
1
    );
452
1
    assert_eq!(Value::Array(Vec::new()).as_array().unwrap(), &[]);
453

            
454
1
    assert!(Value::Null.is_null());
455
1
    assert!(!Value::from(true).is_null());
456
1
    assert_eq!(Value::Null.as_bool(), None);
457
1
    assert_eq!(Value::Null.as_number(), None);
458
1
    assert_eq!(Value::Null.as_string(), None);
459
1
    assert_eq!(Value::Null.as_str(), None);
460
1
    assert_eq!(Value::Null.as_object(), None);
461
1
    assert_eq!(Value::Null.as_array(), None);
462
1
}
463

            
464
impl<'a> Display for Value<'a> {
465
2
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
466
2
        if f.alternate() {
467
1
            self.pretty_write_json_to(f)
468
        } else {
469
1
            self.write_json_to(f)
470
        }
471
2
    }
472
}
473

            
474
pub(crate) struct ValueParser;
475

            
476
impl<'a> ParseDelegate<'a> for ValueParser {
477
    type Array = Vec<Value<'a>>;
478
    type Error = Infallible;
479
    type Key = JsonString<'a>;
480
    type Object = Object<'a>;
481
    type Value = Value<'a>;
482

            
483
    #[inline]
484
75
    fn null(&mut self) -> Result<Self::Value, Self::Error> {
485
75
        Ok(Value::Null)
486
75
    }
487

            
488
    #[inline]
489
187
    fn boolean(&mut self, value: bool) -> Result<Self::Value, Self::Error> {
490
187
        Ok(Value::Boolean(value))
491
187
    }
492

            
493
    #[inline]
494
665
    fn number(&mut self, value: JsonNumber<'a>) -> Result<Self::Value, Self::Error> {
495
665
        Ok(Value::Number(value))
496
665
    }
497

            
498
    #[inline]
499
546
    fn string(&mut self, value: JsonString<'a>) -> Result<Self::Value, Self::Error> {
500
546
        Ok(Value::String(value))
501
546
    }
502

            
503
    #[inline]
504
325
    fn begin_object(&mut self) -> Result<Self::Object, Self::Error> {
505
325
        Ok(Object::default())
506
325
    }
507

            
508
    #[inline]
509
892
    fn object_key(
510
892
        &mut self,
511
892
        _object: &mut Self::Object,
512
892
        key: JsonString<'a>,
513
892
    ) -> Result<Self::Key, Self::Error> {
514
892
        Ok(key)
515
892
    }
516

            
517
    #[inline]
518
829
    fn object_value(
519
829
        &mut self,
520
829
        object: &mut Self::Object,
521
829
        key: Self::Key,
522
829
        value: Self::Value,
523
829
    ) -> Result<(), Self::Error> {
524
829
        object.push(Entry { key, value });
525
829
        Ok(())
526
829
    }
527

            
528
    #[inline]
529
57
    fn object_is_empty(&self, object: &Self::Object) -> bool {
530
57
        object.is_empty()
531
57
    }
532

            
533
    #[inline]
534
183
    fn end_object(&mut self, object: Self::Object) -> Result<Self::Value, Self::Error> {
535
183
        Ok(Value::Object(object))
536
183
    }
537

            
538
    #[inline]
539
971
    fn begin_array(&mut self) -> Result<Self::Array, Self::Error> {
540
971
        Ok(Vec::new())
541
971
    }
542

            
543
    #[inline]
544
1009
    fn array_value(
545
1009
        &mut self,
546
1009
        array: &mut Self::Array,
547
1009
        value: Self::Value,
548
1009
    ) -> Result<(), Self::Error> {
549
1009
        array.push(value);
550
1009
        Ok(())
551
1009
    }
552

            
553
    #[inline]
554
56
    fn array_is_empty(&self, array: &Self::Array) -> bool {
555
56
        array.is_empty()
556
56
    }
557

            
558
    #[inline]
559
514
    fn end_array(&mut self, array: Self::Array) -> Result<Self::Value, Self::Error> {
560
514
        Ok(Value::Array(array))
561
514
    }
562

            
563
    #[inline]
564
89
    fn kind_of(&self, value: &Self::Value) -> JsonKind {
565
89
        match value {
566
1
            Value::Number(_) => JsonKind::Number,
567
13
            Value::String(_) => JsonKind::String,
568
1
            Value::Boolean(_) => JsonKind::Boolean,
569
25
            Value::Object(_) => JsonKind::Object,
570
48
            Value::Array(_) => JsonKind::Array,
571
1
            Value::Null => JsonKind::Null,
572
        }
573
89
    }
574
}
575

            
576
struct WriteState<'a, W, const PRETTY: bool> {
577
    writer: W,
578
    level: usize,
579
    indent_per_level: &'a str,
580
    line_ending: &'a str,
581
    is_at_line_start: bool,
582
}
583

            
584
impl<'a, W, const PRETTY: bool> WriteState<'a, W, PRETTY>
585
where
586
    W: fmt::Write,
587
{
588
171
    fn new(writer: W, indentation: &'a str, line_ending: &'a str) -> Self {
589
171
        Self {
590
171
            writer,
591
171
            level: 0,
592
171
            is_at_line_start: true,
593
171
            indent_per_level: indentation,
594
171
            line_ending,
595
171
        }
596
171
    }
597

            
598
648
    fn write(&mut self, str: &str) -> fmt::Result {
599
648
        if PRETTY && self.is_at_line_start {
600
12
            self.is_at_line_start = false;
601
12

            
602
12
            for _ in 0..self.level {
603
4
                self.writer.write_str(self.indent_per_level)?;
604
            }
605
636
        }
606

            
607
648
        self.writer.write_str(str)?;
608
648
        Ok(())
609
648
    }
610

            
611
76
    fn write_json(&mut self, str: &JsonString<'_>) -> fmt::Result {
612
76
        if PRETTY && self.is_at_line_start {
613
16
            self.is_at_line_start = false;
614
16

            
615
16
            for _ in 0..self.level {
616
16
                self.writer.write_str(self.indent_per_level)?;
617
            }
618
60
        }
619

            
620
76
        write!(self.writer, "\"{}\"", str.as_json())
621
76
    }
622

            
623
362
    fn new_line(&mut self) -> fmt::Result {
624
362
        if PRETTY {
625
24
            self.write(self.line_ending)?;
626
24
            self.is_at_line_start = true;
627
338
        }
628
362
        Ok(())
629
362
    }
630

            
631
    fn begin_object(&mut self) -> fmt::Result {
632
32
        self.write("{")?;
633
32
        self.level += 1;
634
32
        Ok(())
635
32
    }
636

            
637
48
    fn write_object_key_end(&mut self) -> fmt::Result {
638
48
        if PRETTY {
639
15
            self.write(": ")?;
640
        } else {
641
33
            self.write(":")?;
642
        }
643
48
        Ok(())
644
48
    }
645

            
646
32
    fn end_object(&mut self) -> fmt::Result {
647
32
        self.level -= 1;
648
32
        self.write("}")?;
649
32
        Ok(())
650
32
    }
651

            
652
    fn begin_array(&mut self) -> fmt::Result {
653
154
        self.write("[")?;
654
154
        self.level += 1;
655
154
        Ok(())
656
154
    }
657

            
658
154
    fn end_array(&mut self) -> fmt::Result {
659
154
        self.level -= 1;
660
154
        self.write("]")?;
661
154
        Ok(())
662
154
    }
663
}
664

            
665
impl<'a> Index<usize> for Value<'a> {
666
    type Output = Value<'a>;
667

            
668
    /// Returns the contained value at `index`, if this is a [`Value::Array`].
669
    ///
670
    /// # Panics
671
    ///
672
    /// This function panics if the value is not a [`Value::Array`] or if the
673
    /// index is out of bounds of the array.
674
    #[inline]
675
1
    fn index(&self, index: usize) -> &Self::Output {
676
1
        self.get_index(index).expect("index not found")
677
1
    }
678
}
679

            
680
impl<'a> IndexMut<usize> for Value<'a> {
681
    /// Returns a mutable reference to the contained value at `index`, if this
682
    /// is a [`Value::Array`].
683
    ///
684
    /// # Panics
685
    ///
686
    /// This function panics if the value is not a [`Value::Array`] or if the
687
    /// index is out of bounds of the array.
688
    #[inline]
689
1
    fn index_mut(&mut self, index: usize) -> &mut Self::Output {
690
1
        self.get_index_mut(index).expect("index not found")
691
1
    }
692
}
693

            
694
impl<'b, 'a> Index<&'b str> for Value<'a> {
695
    type Output = Value<'a>;
696

            
697
    /// Returns the contained value associated with `key`, if this is a
698
    /// [`Value::Object`].
699
    ///
700
    /// # Panics
701
    ///
702
    /// This function panics if this value is not a [`Value::Object`] or if the
703
    /// `key` is not found.
704
    ///
705
    /// # Performance
706
    ///
707
    /// [`Object`] uses a `Vec` of [`Entry`] types to store its entries. If the
708
    /// operation being performed can be done with a single iteration over the
709
    /// value's contents instead of multiple random accesses, the iteration
710
    /// should be preferred. Additional options to make random access faster in
711
    /// environments that can support it [are being considered][issue] for
712
    /// future releases.
713
    ///
714
    /// [issue]: https://github.com/khonsulabs/justjson/issues/7
715
    #[inline]
716
2
    fn index(&self, index: &'b str) -> &Self::Output {
717
2
        self.get(index).expect("key not found")
718
2
    }
719
}
720

            
721
impl<'b, 'a> IndexMut<&'b str> for Value<'a> {
722
    /// Returns a mutable reference to the contained value associated with
723
    /// `key`, if this is a [`Value::Object`].
724
    ///
725
    /// # Panics
726
    ///
727
    /// This function panics if this value is not a [`Value::Object`] or if the
728
    /// `key` is not found.
729
    ///
730
    /// # Performance
731
    ///
732
    /// [`Object`] uses a `Vec` of [`Entry`] types to store its entries. If the
733
    /// operation being performed can be done with a single iteration over the
734
    /// value's contents instead of multiple random accesses, the iteration
735
    /// should be preferred. Additional options to make random access faster in
736
    /// environments that can support it [are being considered][issue] for
737
    /// future releases.
738
    ///
739
    /// [issue]: https://github.com/khonsulabs/justjson/issues/7
740
    #[inline]
741
3
    fn index_mut(&mut self, index: &'b str) -> &mut Self::Output {
742
3
        self.get_mut(index).expect("key not found")
743
3
    }
744
}
745

            
746
impl<'a> From<bool> for Value<'a> {
747
    #[inline]
748
21
    fn from(value: bool) -> Self {
749
21
        Self::Boolean(value)
750
21
    }
751
}
752

            
753
impl<'a> From<Object<'a>> for Value<'a> {
754
    #[inline]
755
1
    fn from(value: Object<'a>) -> Self {
756
1
        Self::Object(value)
757
1
    }
758
}
759

            
760
impl<'a> From<Vec<Value<'a>>> for Value<'a> {
761
    #[inline]
762
1
    fn from(value: Vec<Value<'a>>) -> Self {
763
1
        Self::Array(value)
764
1
    }
765
}
766

            
767
impl<'a> From<&'a str> for Value<'a> {
768
    #[inline]
769
1
    fn from(value: &'a str) -> Self {
770
1
        Self::from(JsonString::from(value))
771
1
    }
772
}
773

            
774
impl<'a> From<String> for Value<'a> {
775
    #[inline]
776
1
    fn from(value: String) -> Self {
777
1
        Self::from(JsonString::from(value))
778
1
    }
779
}
780

            
781
impl<'a> From<JsonString<'a>> for Value<'a> {
782
    #[inline]
783
10
    fn from(value: JsonString<'a>) -> Self {
784
10
        Self::String(value)
785
10
    }
786
}
787

            
788
/// A JSON Object (list of key-value pairs).
789
///
790
/// # Performance
791
///
792
/// [`Object`] uses a `Vec` of [`Entry`] types to store its entries. If the
793
/// operation being performed can be done with a single iteration over the
794
/// value's contents instead of multiple random accesses, the iteration should
795
/// be preferred. Additional options to make random access faster in
796
/// environments that can support it [are being considered][issue] for future
797
/// releases.
798
///
799
/// # Modifying an Object
800
///
801
/// Because [`Object`] internally is just a `Vec<Entry>`, it implements
802
/// `Deref`/`DerefMut` to its internal storage. This means that all of `Vec`'s
803
/// methods are available to change the contents of an object.
804
///
805
/// ```rust
806
/// use justjson::{Entry, Object, Value};
807
///
808
/// let mut obj = Object::new();
809
/// obj.push(Entry::new("hello", "world"));
810
///
811
/// assert_eq!(Value::Object(obj).to_json(), r#"{"hello":"world"}"#)
812
/// ```
813
///
814
/// [issue]: https://github.com/khonsulabs/justjson/issues/7
815
24
#[derive(Debug, Eq, PartialEq)]
816
pub struct Object<'a>(Vec<Entry<'a>>);
817

            
818
impl<'a> Default for Object<'a> {
819
    #[inline]
820
326
    fn default() -> Self {
821
326
        Self::new()
822
326
    }
823
}
824

            
825
impl<'a> Object<'a> {
826
    /// Returns an empty object.
827
    #[must_use]
828
    #[inline]
829
333
    pub const fn new() -> Self {
830
333
        Self(Vec::new())
831
333
    }
832

            
833
    /// Returns an empty object that can store up to `capacity` elements without
834
    /// reallocating.
835
    #[must_use]
836
    #[inline]
837
12
    pub fn with_capacity(capacity: usize) -> Self {
838
12
        Self(Vec::with_capacity(capacity))
839
12
    }
840

            
841
    /// Returns the value associated with `key`, if found.
842
    #[must_use]
843
    #[inline]
844
2
    pub fn get(&self, key: &str) -> Option<&Value<'a>> {
845
2
        self.iter()
846
3
            .find_map(|entry| (entry.key == key).then_some(&entry.value))
847
2
    }
848

            
849
    /// Returns a mutable reference to the value associated with `key`, if
850
    /// found.
851
    #[must_use]
852
    #[inline]
853
3
    pub fn get_mut(&mut self, key: &str) -> Option<&mut Value<'a>> {
854
3
        self.get_entry_mut(key).map(|entry| &mut entry.value)
855
3
    }
856

            
857
    /// Returns a mutable reference to the entry associated with `key`, if
858
    /// found.
859
    #[must_use]
860
    #[inline]
861
3
    pub fn get_entry_mut(&mut self, key: &str) -> Option<&mut Entry<'a>> {
862
8
        self.iter_mut().find(|entry| entry.key == key)
863
3
    }
864
}
865

            
866
impl<'a> Deref for Object<'a> {
867
    type Target = Vec<Entry<'a>>;
868

            
869
    #[inline]
870
61
    fn deref(&self) -> &Self::Target {
871
61
        &self.0
872
61
    }
873
}
874

            
875
impl<'a> DerefMut for Object<'a> {
876
    #[inline]
877
853
    fn deref_mut(&mut self) -> &mut Self::Target {
878
853
        &mut self.0
879
853
    }
880
}
881

            
882
impl<'a> FromIterator<(JsonString<'a>, Value<'a>)> for Object<'a> {
883
5
    fn from_iter<T: IntoIterator<Item = (JsonString<'a>, Value<'a>)>>(iter: T) -> Self {
884
5
        iter.into_iter()
885
11
            .map(|(key, value)| Entry { key, value })
886
5
            .collect()
887
5
    }
888
}
889

            
890
impl<'a> FromIterator<Entry<'a>> for Object<'a> {
891
6
    fn from_iter<T: IntoIterator<Item = Entry<'a>>>(iter: T) -> Self {
892
6
        Self(iter.into_iter().collect())
893
6
    }
894
}
895

            
896
/// An key-value pair in an [`Object`].
897
31
#[derive(Debug, Eq, PartialEq)]
898
pub struct Entry<'a> {
899
    /// The key of this entry.
900
    pub key: JsonString<'a>,
901
    /// The value associated with the key.
902
    pub value: Value<'a>,
903
}
904

            
905
impl<'a> Entry<'a> {
906
    /// Returns a new entry for the given key and value.
907
    #[inline]
908
2
    pub fn new(key: impl Into<JsonString<'a>>, value: impl Into<Value<'a>>) -> Self {
909
2
        Self {
910
2
            key: key.into(),
911
2
            value: value.into(),
912
2
        }
913
2
    }
914
}
915

            
916
1
#[test]
917
1
fn primitive_values() {
918
1
    assert_eq!(Value::from_json("true").unwrap(), Value::from(true));
919
1
    assert_eq!(Value::from_json("false").unwrap(), Value::from(false));
920
1
    assert_eq!(Value::from_json("null").unwrap(), Value::Null);
921
1
}
922

            
923
1
#[test]
924
1
fn objects() {
925
1
    assert_eq!(
926
1
        Value::from_json("{}").unwrap(),
927
1
        Value::Object(Object::default())
928
1
    );
929
1
    assert_eq!(
930
1
        Value::from_json(r#"{"hello":"world"}"#).unwrap(),
931
1
        Value::Object(Object::from_iter([(
932
1
            JsonString::from_json(r#""hello""#).unwrap(),
933
1
            Value::String(JsonString::from_json(r#""world""#).unwrap())
934
1
        )]))
935
1
    );
936
1
    assert_eq!(
937
1
        Value::from_json(r#" { "hello" : "world" , "another" : "value" }"#).unwrap(),
938
1
        Value::Object(Object::from_iter([
939
1
            Entry::new(
940
1
                JsonString::from_json(r#""hello""#).unwrap(),
941
1
                Value::String(JsonString::from_json(r#""world""#).unwrap())
942
1
            ),
943
1
            Entry::new(
944
1
                JsonString::from_json(r#""another""#).unwrap(),
945
1
                Value::String(JsonString::from_json(r#""value""#).unwrap())
946
1
            )
947
1
        ]))
948
1
    );
949
1
}
950

            
951
1
#[test]
952
1
fn cow() {
953
1
    let mut value =
954
1
        Value::from_json_bytes(br#"{"a":1,"b":true,"c":"hello","d":[],"e":{}}"#).unwrap();
955
1
    value["b"] = Value::from(false);
956
1
    let root = value.as_object_mut().unwrap();
957
1
    root[0].key = JsonString::from("newa");
958
1
    root[0].value = JsonString::from("a").into();
959
1
    let Value::Array(d_array) = &mut root[3].value else {
960
        unreachable!()
961
    };
962
1
    d_array.push(Value::Null);
963
1

            
964
1
    // Replace the newly inserted null (uses IndexMut on the array).
965
1
    value["d"][0] = Value::from(false);
966
1

            
967
1
    let generated = value.to_json();
968
1
    assert_eq!(
969
1
        generated,
970
1
        r#"{"newa":"a","b":false,"c":"hello","d":[false],"e":{}}"#
971
1
    );
972
1
}
973

            
974
1
#[test]
975
1
fn index() {
976
1
    let mut value = Value::from_json_bytes(br#"{"b":true,"a":[false]}"#).unwrap();
977
1
    assert_eq!(value["b"], Value::from(true));
978
1
    assert_eq!(value.get_index_mut(0), None);
979
1
    assert_eq!(value["a"][0], Value::from(false));
980
1
    assert_eq!(value["a"].get_mut("a"), None);
981
1
}
982

            
983
1
#[test]
984
1
fn froms() {
985
1
    assert_eq!(Value::from(true), Value::Boolean(true));
986
1
    assert_eq!(Value::from(Object::new()), Value::Object(Object::new()));
987
1
    assert_eq!(Value::from(Vec::new()), Value::Array(Vec::new()));
988
1
    assert_eq!(
989
1
        Value::from(String::from("a")),
990
1
        Value::String(JsonString::from("a"))
991
1
    );
992
1
    assert_eq!(Value::from("a"), Value::String(JsonString::from("a")));
993
1
    assert_eq!(
994
1
        Value::from(JsonString::from("a")),
995
1
        Value::String(JsonString::from("a"))
996
1
    );
997
1
}
998

            
999
1
#[test]
1
fn as_es() {
1
    macro_rules! test_as {
1
        ($as:ident) => {
1
            assert_eq!(
1
                Value::Number(JsonNumber::from_json("1").unwrap()).$as(),
1
                Some(1)
1
            );
1
        };
1
    }
1

            
1
    test_as!(as_i8);
1
    test_as!(as_i16);
1
    test_as!(as_i32);
1
    test_as!(as_i64);
1
    test_as!(as_i128);
1
    test_as!(as_isize);
1
    test_as!(as_u8);
1
    test_as!(as_u16);
1
    test_as!(as_u32);
1
    test_as!(as_u64);
1
    test_as!(as_u128);
1
    test_as!(as_usize);

            
1
    assert!(
1
        Value::Number(JsonNumber::from_json("0").unwrap())
1
            .as_f32()
1
            .unwrap()
1
            .abs()
1
            < f32::EPSILON
    );
1
    assert!(
1
        Value::Number(JsonNumber::from_json("0").unwrap())
1
            .as_f64()
1
            .unwrap()
1
            .abs()
1
            < f64::EPSILON
    );
1
}