simd_json/value/
lazy.rs

1//! Lazy value, uses a tape until mutated.
2//!
3//! If it is mutated it is upgraded to a borrowed value.
4//! This allows for cheap parsing and data access while still maintaining mutability.
5//!
6//! # Example
7//!
8//! ```rust
9//! use simd_json::{prelude::*, value::lazy::Value};
10//!
11//! let mut json = br#"{"key": "value", "snot": 42}"#.to_vec();
12//! let tape = simd_json::to_tape( json.as_mut_slice()).unwrap();
13//! let value = tape.as_value();
14//! let mut lazy = Value::from_tape(value);
15//!
16//! assert_eq!(lazy.get("key").unwrap(), "value");
17//!
18//! assert!(lazy.is_tape());
19//! lazy.insert("new", 42);
20//! assert!(lazy.is_value());
21//! assert_eq!(lazy.get("key").unwrap(), "value");
22//! assert_eq!(lazy.get("new").unwrap(), 42);
23//! ```
24
25use crate::{borrowed, tape};
26use std::borrow::Cow;
27use std::fmt;
28
29/// Lazy implemntation of the array trait and associated functionality
30pub mod array;
31mod cmp;
32mod from;
33/// Lazy implementation of the object trait and associated functionality
34pub mod object;
35mod trait_impls;
36
37pub use array::Array;
38pub use object::Object;
39
40/// A lazy value, this gets initialized with a tape and as long as only non mutating operations are
41/// performed it will stay a tape. If a mutating operation is performed it will upgrade to a borrowed
42/// value.
43#[derive(Clone, Debug, PartialEq)]
44pub enum Value<'borrow, 'tape, 'input> {
45    /// tape variant
46    Tape(tape::Value<'tape, 'input>),
47    /// borrowed variant
48    Value(Cow<'borrow, borrowed::Value<'input>>),
49}
50
51impl Default for Value<'static, 'static, '_> {
52    #[cfg_attr(not(feature = "no-inline"), inline)]
53    fn default() -> Self {
54        Value::Tape(tape::Value::null())
55    }
56}
57
58impl<'tape, 'input> Value<'_, 'tape, 'input> {
59    /// turns the lazy value into a borrowed value
60    #[must_use]
61    pub fn into_value(self) -> borrowed::Value<'input> {
62        match self {
63            Value::Tape(tape) => {
64                super::borrowed::BorrowSliceDeserializer::from_tape(tape.0).parse()
65            }
66            Value::Value(value) => value.into_owned(),
67        }
68    }
69    /// extends the Value COW is owned
70    #[must_use]
71    pub fn into_owned<'snot>(self) -> Value<'snot, 'tape, 'input> {
72        match self {
73            Value::Tape(tape) => Value::Tape(tape),
74            Value::Value(Cow::Owned(value)) => Value::Value(Cow::Owned(value)),
75            Value::Value(Cow::Borrowed(value)) => Value::Value(Cow::Owned(value.clone())),
76        }
77    }
78    /// returns true when the current representation is a tape
79    #[must_use]
80    pub fn is_tape(&self) -> bool {
81        match self {
82            Value::Tape(_) => true,
83            Value::Value(_) => false,
84        }
85    }
86    /// returns true when the current representation is a borrowed value
87    /// this is the opposite of `is_tape`
88    #[must_use]
89    pub fn is_value(&self) -> bool {
90        !self.is_tape()
91    }
92    /// Creates a new lazy Value from a tape
93    #[must_use]
94    pub fn from_tape(tape: tape::Value<'tape, 'input>) -> Self {
95        Value::Tape(tape)
96    }
97    unsafe fn into_tape(self) -> tape::Value<'tape, 'input> {
98        match self {
99            Value::Tape(tape) => tape,
100            Value::Value(_) => unreachable!("we know we are not a value"),
101        }
102    }
103
104    fn upgrade(&mut self) {
105        if let Value::Value(_) = &self {
106            return;
107        }
108        let mut dummy = Value::Tape(tape::Value::null());
109        std::mem::swap(self, &mut dummy);
110        let tape = unsafe { dummy.into_tape() };
111
112        let value = super::borrowed::BorrowSliceDeserializer::from_tape(tape.0).parse();
113
114        *self = Value::Value(Cow::Owned(value));
115    }
116
117    fn as_mut(&mut self) -> &mut borrowed::Value<'input> {
118        if self.is_tape() {
119            self.upgrade();
120        }
121
122        if let Value::Value(value) = self {
123            value.to_mut()
124        } else {
125            unreachable!("can't mut a tape");
126        }
127    }
128}
129
130#[cfg(not(tarpaulin_include))]
131impl fmt::Display for Value<'_, '_, '_> {
132    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
133        match &self {
134            Value::Tape(tape) => write!(f, "{tape:?}"),
135            Value::Value(value) => write!(f, "{value}"),
136        }
137    }
138}
139
140// impl<'value> Index<&str> for Value<'value> {
141//     type Output = Value<'value>;
142//     #[cfg_attr(not(feature = "no-inline"), inline)]
143//     #[must_use]
144//     fn index(&self, index: &str) -> &Self::Output {
145//         self.get(index).expect("index out of bounds")
146//     }
147// }
148
149// impl<'value> Index<usize> for Value<'value> {
150//     type Output = Value<'value>;
151//     #[cfg_attr(not(feature = "no-inline"), inline)]
152//     #[must_use]
153//     fn index(&self, index: usize) -> &Self::Output {
154//         self.get_idx(index).expect("index out of bounds")
155//     }
156// }
157
158// impl<'value> IndexMut<&str> for Value<'value> {
159//     #[cfg_attr(not(feature = "no-inline"), inline)]
160//     #[must_use]
161//     fn index_mut(&mut self, index: &str) -> &mut Self::Output {
162//         self.get_mut(index).expect("index out of bounds")
163//     }
164// }
165
166// impl<'value> IndexMut<usize> for Value<'value> {
167//     #[cfg_attr(not(feature = "no-inline"), inline)]
168//     #[must_use]
169//     fn index_mut(&mut self, index: usize) -> &mut Self::Output {
170//         self.get_idx_mut(index).expect("index out of bounds")
171//     }
172// }
173
174#[cfg(test)]
175mod test {
176    #![allow(clippy::cognitive_complexity)]
177    use value_trait::prelude::*;
178
179    use super::Value;
180
181    #[test]
182    #[should_panic = "Not supported"]
183    #[allow(unused_variables, clippy::no_effect)]
184    fn object_index() {
185        let v = StaticNode::Null;
186        v["test"];
187    }
188
189    #[test]
190    #[should_panic = "Not supported"]
191    fn mut_object_index() {
192        let mut v = StaticNode::Null;
193        v["test"] = ();
194    }
195
196    #[test]
197    #[should_panic = "Not supported"]
198    #[allow(unused_variables, clippy::no_effect)]
199    fn array_index() {
200        let v = StaticNode::Null;
201        v[0];
202    }
203
204    #[test]
205    #[should_panic = "Not supported"]
206    fn mut_array_index() {
207        let mut v = StaticNode::Null;
208        v[0] = ();
209    }
210
211    #[test]
212    fn conversion_str() {
213        let v = StaticNode::Null;
214        assert!(!v.is_str());
215    }
216    #[cfg(feature = "128bit")]
217    #[test]
218    fn conversions_i128() {
219        let v = Value::from(i128::MAX);
220        assert!(v.is_i128());
221        assert!(v.is_u128());
222        assert!(!v.is_i64());
223        assert!(!v.is_u64());
224        assert!(!v.is_i32());
225        assert!(!v.is_u32());
226        assert!(!v.is_i16());
227        assert!(!v.is_u16());
228        assert!(!v.is_i8());
229        assert!(!v.is_u8());
230        assert!(!v.is_f64());
231        assert!(!v.is_f32());
232        assert!(v.is_f64_castable());
233        let v = Value::from(i128::MIN);
234        assert!(v.is_i128());
235        assert!(!v.is_u128());
236        assert!(!v.is_i64());
237        assert!(!v.is_u64());
238        assert!(!v.is_i32());
239        assert!(!v.is_u32());
240        assert!(!v.is_i16());
241        assert!(!v.is_u16());
242        assert!(!v.is_i8());
243        assert!(!v.is_u8());
244        assert!(!v.is_f64());
245        assert!(!v.is_f32());
246        assert!(v.is_f64_castable());
247    }
248
249    #[test]
250    fn conversions_i64() {
251        let v = Value::from(i64::MAX);
252        assert!(v.is_i128());
253        assert!(v.is_u128());
254        assert!(v.is_i64());
255        assert!(v.is_u64());
256        assert!(!v.is_i32());
257        assert!(!v.is_u32());
258        assert!(!v.is_i16());
259        assert!(!v.is_u16());
260        assert!(!v.is_i8());
261        assert!(!v.is_u8());
262        assert!(!v.is_f64());
263        assert!(!v.is_f32());
264        assert!(v.is_f64_castable());
265        let v = Value::from(i64::MIN);
266        assert!(v.is_i128());
267        assert!(!v.is_u128());
268        assert!(v.is_i64());
269        assert!(!v.is_u64());
270        assert!(!v.is_i32());
271        assert!(!v.is_u32());
272        assert!(!v.is_i16());
273        assert!(!v.is_u16());
274        assert!(!v.is_i8());
275        assert!(!v.is_u8());
276        assert!(!v.is_f64());
277        assert!(!v.is_f32());
278        assert!(v.is_f64_castable());
279    }
280
281    #[test]
282    fn conversions_i32() {
283        let v = Value::from(i32::MAX);
284        assert!(v.is_i128());
285        assert!(v.is_u128());
286        assert!(v.is_i64());
287        assert!(v.is_u64());
288        assert!(v.is_i32());
289        assert!(v.is_u32());
290        assert!(!v.is_i16());
291        assert!(!v.is_u16());
292        assert!(!v.is_i8());
293        assert!(!v.is_u8());
294        assert!(!v.is_f64());
295        assert!(!v.is_f32());
296        assert!(v.is_f64_castable());
297        let v = Value::from(i32::MIN);
298        assert!(v.is_i128());
299        assert!(!v.is_u128());
300        assert!(v.is_i64());
301        assert!(!v.is_u64());
302        assert!(v.is_i32());
303        assert!(!v.is_u32());
304        assert!(!v.is_i16());
305        assert!(!v.is_u16());
306        assert!(!v.is_i8());
307        assert!(!v.is_u8());
308        assert!(!v.is_f64());
309        assert!(!v.is_f32());
310        assert!(v.is_f64_castable());
311    }
312
313    #[test]
314    fn conversions_i16() {
315        let v = Value::from(i16::MAX);
316        assert!(v.is_i128());
317        assert!(v.is_u128());
318        assert!(v.is_i64());
319        assert!(v.is_u64());
320        assert!(v.is_i32());
321        assert!(v.is_u32());
322        assert!(v.is_i16());
323        assert!(v.is_u16());
324        assert!(!v.is_i8());
325        assert!(!v.is_u8());
326        assert!(!v.is_f64());
327        assert!(!v.is_f32());
328        assert!(v.is_f64_castable());
329        let v = Value::from(i16::MIN);
330        assert!(v.is_i128());
331        assert!(!v.is_u128());
332        assert!(v.is_i64());
333        assert!(!v.is_u64());
334        assert!(v.is_i32());
335        assert!(!v.is_u32());
336        assert!(v.is_i16());
337        assert!(!v.is_u16());
338        assert!(!v.is_i8());
339        assert!(!v.is_u8());
340        assert!(!v.is_f64());
341        assert!(!v.is_f32());
342        assert!(v.is_f64_castable());
343        assert!(v.is_f64_castable());
344    }
345
346    #[test]
347    fn conversions_i8() {
348        let v = Value::from(i8::MAX);
349        assert!(v.is_i128());
350        assert!(v.is_u128());
351        assert!(v.is_i64());
352        assert!(v.is_u64());
353        assert!(v.is_i32());
354        assert!(v.is_u32());
355        assert!(v.is_i16());
356        assert!(v.is_u16());
357        assert!(v.is_i8());
358        assert!(v.is_u8());
359        assert!(!v.is_f64());
360        assert!(!v.is_f32());
361        assert!(v.is_f64_castable());
362        let v = Value::from(i8::MIN);
363        assert!(v.is_i128());
364        assert!(!v.is_u128());
365        assert!(v.is_i64());
366        assert!(!v.is_u64());
367        assert!(v.is_i32());
368        assert!(!v.is_u32());
369        assert!(v.is_i16());
370        assert!(!v.is_u16());
371        assert!(v.is_i8());
372        assert!(!v.is_u8());
373        assert!(!v.is_f64());
374        assert!(!v.is_f32());
375        assert!(v.is_f64_castable());
376    }
377
378    #[test]
379    fn conversions_usize() {
380        let v = Value::from(usize::MIN as u64);
381        assert!(v.is_i128());
382        assert!(v.is_u128());
383        assert!(v.is_i64());
384        assert!(v.is_u64());
385        assert!(v.is_usize());
386        assert!(v.is_i32());
387        assert!(v.is_u32());
388        assert!(v.is_i16());
389        assert!(v.is_u16());
390        assert!(v.is_i8());
391        assert!(v.is_u8());
392        assert!(!v.is_f64());
393        assert!(!v.is_f32());
394        assert!(!v.is_f64());
395        assert!(!v.is_f32());
396        assert!(v.is_f64_castable());
397    }
398
399    #[cfg(feature = "128bit")]
400    #[test]
401    fn conversions_u128() {
402        let v = Value::from(u128::MIN);
403        assert!(v.is_i128());
404        assert!(v.is_u128());
405        assert!(v.is_i64());
406        assert!(v.is_u64());
407        assert!(v.is_i32());
408        assert!(v.is_u32());
409        assert!(v.is_i16());
410        assert!(v.is_u16());
411        assert!(v.is_i8());
412        assert!(v.is_u8());
413        assert!(!v.is_f64());
414        assert!(!v.is_f32());
415        assert!(v.is_f64_castable());
416    }
417
418    #[test]
419    fn conversions_u64() {
420        let v = Value::from(u64::MIN);
421        assert!(v.is_i128());
422        assert!(v.is_u128());
423        assert!(v.is_i64());
424        assert!(v.is_u64());
425        assert!(v.is_i32());
426        assert!(v.is_u32());
427        assert!(v.is_i16());
428        assert!(v.is_u16());
429        assert!(v.is_i8());
430        assert!(v.is_u8());
431        assert!(!v.is_f64());
432        assert!(!v.is_f32());
433        assert!(v.is_f64_castable());
434    }
435
436    #[test]
437    fn conversions_u32() {
438        let v = Value::from(u32::MAX);
439        assert!(v.is_i128());
440        assert!(v.is_u128());
441        assert!(v.is_i64());
442        assert!(v.is_u64());
443        assert!(!v.is_i32());
444        assert!(v.is_u32());
445        assert!(!v.is_i16());
446        assert!(!v.is_u16());
447        assert!(!v.is_i8());
448        assert!(!v.is_u8());
449        assert!(!v.is_f64());
450        assert!(!v.is_f32());
451        assert!(v.is_f64_castable());
452    }
453
454    #[test]
455    fn conversions_u16() {
456        let v = Value::from(u16::MAX);
457        assert!(v.is_i128());
458        assert!(v.is_u128());
459        assert!(v.is_i64());
460        assert!(v.is_u64());
461        assert!(v.is_i32());
462        assert!(v.is_u32());
463        assert!(!v.is_i16());
464        assert!(v.is_u16());
465        assert!(!v.is_i8());
466        assert!(!v.is_u8());
467        assert!(!v.is_f64());
468        assert!(!v.is_f32());
469        assert!(v.is_f64_castable());
470    }
471
472    #[test]
473    fn conversions_u8() {
474        let v = Value::from(u8::MAX);
475        assert!(v.is_i128());
476        assert!(v.is_u128());
477        assert!(v.is_i64());
478        assert!(v.is_u64());
479        assert!(v.is_i32());
480        assert!(v.is_u32());
481        assert!(v.is_i16());
482        assert!(v.is_u16());
483        assert!(!v.is_i8());
484        assert!(v.is_u8());
485        assert!(!v.is_f64());
486        assert!(!v.is_f32());
487        assert!(v.is_f64_castable());
488    }
489
490    #[test]
491    fn conversions_f64() {
492        let v = Value::from(f64::MAX);
493        assert!(!v.is_i64());
494        assert!(!v.is_u64());
495        assert!(v.is_f64());
496        assert!(!v.is_f32());
497        assert!(v.is_f64_castable());
498        let v = Value::from(f64::MIN);
499        assert!(!v.is_i64());
500        assert!(!v.is_u64());
501        assert!(v.is_f64());
502        assert!(!v.is_f32());
503        assert!(v.is_f64_castable());
504        let v = Value::from(());
505        assert!(!v.is_f64_castable());
506    }
507
508    #[test]
509    fn conversions_f32() {
510        let v = Value::from(f32::MAX);
511        assert!(!v.is_i64());
512        assert!(!v.is_u64());
513        assert!(v.is_f64());
514        assert!(v.is_f32());
515        assert!(v.is_f64_castable());
516        let v = Value::from(f32::MIN);
517        assert!(!v.is_i64());
518        assert!(!v.is_u64());
519        assert!(v.is_f64());
520        assert!(v.is_f32());
521        assert!(v.is_f64_castable());
522    }
523
524    #[test]
525    fn conversions_bool() {
526        let v = Value::from(true);
527        assert!(v.is_bool());
528        assert_eq!(v.value_type(), ValueType::Bool);
529        let v = Value::from(());
530        assert!(!v.is_bool());
531    }
532
533    #[test]
534    fn conversions_float() {
535        let v = Value::from(42.0);
536        assert!(v.is_f64());
537        assert_eq!(v.value_type(), ValueType::F64);
538        let v = Value::from(());
539        assert!(!v.is_f64());
540    }
541
542    #[test]
543    fn conversions_int() {
544        let v = Value::from(-42);
545        assert!(v.is_i64());
546        assert_eq!(v.value_type(), ValueType::I64);
547        #[cfg(feature = "128bit")]
548        {
549            let v = Value::from(-42_i128);
550            assert!(v.is_i64());
551            assert!(v.is_i128());
552            assert_eq!(v.value_type(), ValueType::I128);
553        }
554        let v = Value::from(());
555        assert!(!v.is_i64());
556        assert!(!v.is_i128());
557    }
558
559    #[test]
560    fn conversions_uint() {
561        let v = Value::from(42_u64);
562        assert!(v.is_u64());
563        assert_eq!(v.value_type(), ValueType::U64);
564        #[cfg(feature = "128bit")]
565        {
566            let v = Value::from(42_u128);
567            assert!(v.is_u64());
568            assert!(v.is_u128());
569            assert_eq!(v.value_type(), ValueType::U128);
570        }
571        let v = Value::from(());
572        assert!(!v.is_u64());
573        assert!(!v.is_u128());
574    }
575
576    #[test]
577    fn conversions_null() {
578        let v = Value::from(());
579        assert!(v.is_null());
580        assert_eq!(v.value_type(), ValueType::Null);
581        let v = Value::from(1);
582        assert!(!v.is_null());
583    }
584
585    #[test]
586    fn default() {
587        assert_eq!(Value::default(), Value::null());
588    }
589
590    #[test]
591    fn mixed_int_cmp() {
592        assert_eq!(Value::from(1_u64), Value::from(1_i64));
593        assert_eq!(Value::from(1_i64), Value::from(1_u64));
594    }
595
596    #[test]
597    #[cfg(feature = "128bit")]
598    fn mixed_int_cmp_128() {
599        assert_eq!(Value::from(1_u64), Value::from(1_u128));
600        assert_eq!(Value::from(1_u64), Value::from(1_i128));
601        assert_eq!(Value::from(1_i64), Value::from(1_u128));
602        assert_eq!(Value::from(1_i64), Value::from(1_i128));
603
604        assert_eq!(Value::from(1_u128), Value::from(1_u128));
605        assert_eq!(Value::from(1_u128), Value::from(1_i128));
606        assert_eq!(Value::from(1_u128), Value::from(1_u64));
607        assert_eq!(Value::from(1_u128), Value::from(1_i64));
608
609        assert_eq!(Value::from(1_i128), Value::from(1_u128));
610        assert_eq!(Value::from(1_i128), Value::from(1_i128));
611        assert_eq!(Value::from(1_i128), Value::from(1_u64));
612        assert_eq!(Value::from(1_i128), Value::from(1_i64));
613    }
614
615    #[test]
616    fn test_union_cmp() {
617        let v: Value = ().into();
618        assert_eq!(v, ());
619    }
620    #[test]
621    #[allow(clippy::bool_assert_comparison)]
622    fn test_bool_cmp() {
623        let v: Value = true.into();
624        assert_eq!(v, true);
625        let v: Value = false.into();
626        assert_eq!(v, false);
627    }
628}