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