simd_json/value/
owned.rs

1/// A lifetime less DOM implementation. It uses strings to make te
2/// structure fully owned, avoiding lifetimes at the cost of performance.
3/// Access via array indexes is possible:
4/// ```rust
5/// use simd_json::{OwnedValue, json};
6/// use simd_json::prelude::*;
7/// let mut a = json!([1, 2, 3]);
8/// assert_eq!(a[1], 2);
9/// a[1] = 42.into();
10/// assert_eq!(a[1], 42);
11/// ```
12///
13/// Access via object keys is possible as well:
14/// ```rust
15/// use simd_json::{OwnedValue, json};
16/// use simd_json::prelude::*;
17/// let mut a = json!({"key": "not the value"});
18/// assert_eq!(a["key"], "not the value");
19/// a["key"] = "value".into();
20/// assert_eq!(a["key"], "value");
21/// ```
22mod cmp;
23mod from;
24mod serialize;
25
26use super::ObjectHasher;
27use crate::{Buffers, prelude::*};
28use crate::{Deserializer, Node, Result};
29use halfbrown::HashMap;
30use std::fmt;
31use std::ops::{Index, IndexMut};
32
33/// Representation of a JSON object
34pub type Object = HashMap<String, Value, ObjectHasher>;
35
36/// Parses a slice of bytes into a Value dom.
37///
38/// This function will rewrite the slice to de-escape strings.
39/// We do not keep any references to the raw data but re-allocate
40/// owned memory wherever required thus returning a value without
41/// a lifetime.
42///
43/// # Errors
44///
45/// Will return `Err` if `s` is invalid JSON.
46pub fn to_value(s: &mut [u8]) -> Result<Value> {
47    match Deserializer::from_slice(s) {
48        Ok(de) => Ok(OwnedDeserializer::from_deserializer(de).parse()),
49        Err(e) => Err(e),
50    }
51}
52
53/// Parses a slice of bytes into a Value dom.
54///
55/// This function will rewrite the slice to de-escape strings.
56/// We do not keep any references to the raw data but re-allocate
57/// owned memory wherever required thus returning a value without
58/// a lifetime.
59///
60/// Passes in reusable buffers to reduce allocations.
61///
62/// # Errors
63///
64/// Will return `Err` if `s` is invalid JSON.
65pub fn to_value_with_buffers(s: &mut [u8], buffers: &mut Buffers) -> Result<Value> {
66    match Deserializer::from_slice_with_buffers(s, buffers) {
67        Ok(de) => Ok(OwnedDeserializer::from_deserializer(de).parse()),
68        Err(e) => Err(e),
69    }
70}
71
72/// Owned JSON-DOM Value, consider using the `ValueTrait`
73/// to access it's content.
74/// This is slower then the `BorrowedValue` as a tradeoff
75/// for getting rid of lifetimes.
76#[derive(Debug, Clone)]
77#[cfg_attr(feature = "ordered-float", derive(Eq))]
78pub enum Value {
79    /// Static values
80    Static(StaticNode),
81    /// string type
82    String(String),
83    /// array type
84    Array(Box<Vec<Value>>),
85    /// object type
86    Object(Box<Object>),
87}
88
89impl Value {
90    fn as_static(&self) -> Option<StaticNode> {
91        match self {
92            Value::Static(s) => Some(*s),
93            _ => None,
94        }
95    }
96}
97
98impl ValueBuilder<'_> for Value {
99    #[cfg_attr(not(feature = "no-inline"), inline)]
100    fn null() -> Self {
101        Self::Static(StaticNode::Null)
102    }
103    #[cfg_attr(not(feature = "no-inline"), inline)]
104    fn array_with_capacity(capacity: usize) -> Self {
105        Self::Array(Box::new(Vec::with_capacity(capacity)))
106    }
107    #[cfg_attr(not(feature = "no-inline"), inline)]
108    fn object_with_capacity(capacity: usize) -> Self {
109        Self::Object(Box::new(Object::with_capacity_and_hasher(
110            capacity,
111            ObjectHasher::default(),
112        )))
113    }
114}
115
116impl ValueAsMutArray for Value {
117    type Array = Vec<Self>;
118    #[cfg_attr(not(feature = "no-inline"), inline)]
119    fn as_array_mut(&mut self) -> Option<&mut Vec<Self>> {
120        match self {
121            Self::Array(a) => Some(a),
122            _ => None,
123        }
124    }
125}
126impl ValueAsMutObject for Value {
127    type Object = Object;
128    #[cfg_attr(not(feature = "no-inline"), inline)]
129    fn as_object_mut(&mut self) -> Option<&mut Object> {
130        match self {
131            Self::Object(m) => Some(m),
132            _ => None,
133        }
134    }
135}
136
137impl TypedValue for Value {
138    #[cfg_attr(not(feature = "no-inline"), inline)]
139    fn value_type(&self) -> ValueType {
140        match self {
141            Self::Static(s) => s.value_type(),
142            Self::String(_) => ValueType::String,
143            Self::Array(_) => ValueType::Array,
144            Self::Object(_) => ValueType::Object,
145        }
146    }
147}
148impl ValueAsScalar for Value {
149    #[cfg_attr(not(feature = "no-inline"), inline)]
150    fn as_null(&self) -> Option<()> {
151        self.as_static()?.as_null()
152    }
153    #[cfg_attr(not(feature = "no-inline"), inline)]
154    fn as_bool(&self) -> Option<bool> {
155        self.as_static()?.as_bool()
156    }
157
158    #[cfg_attr(not(feature = "no-inline"), inline)]
159    fn as_i64(&self) -> Option<i64> {
160        self.as_static()?.as_i64()
161    }
162
163    #[cfg_attr(not(feature = "no-inline"), inline)]
164    fn as_i128(&self) -> Option<i128> {
165        self.as_static()?.as_i128()
166    }
167
168    #[cfg_attr(not(feature = "no-inline"), inline)]
169    fn as_u64(&self) -> Option<u64> {
170        self.as_static()?.as_u64()
171    }
172
173    #[cfg_attr(not(feature = "no-inline"), inline)]
174    fn as_u128(&self) -> Option<u128> {
175        self.as_static()?.as_u128()
176    }
177
178    #[cfg_attr(not(feature = "no-inline"), inline)]
179    fn as_f64(&self) -> Option<f64> {
180        self.as_static()?.as_f64()
181    }
182
183    #[cfg_attr(not(feature = "no-inline"), inline)]
184    fn cast_f64(&self) -> Option<f64> {
185        self.as_static()?.cast_f64()
186    }
187
188    #[cfg_attr(not(feature = "no-inline"), inline)]
189    fn as_str(&self) -> Option<&str> {
190        match self {
191            Self::String(s) => Some(s.as_str()),
192            _ => None,
193        }
194    }
195}
196impl ValueAsArray for Value {
197    type Array = Vec<Self>;
198    #[cfg_attr(not(feature = "no-inline"), inline)]
199    fn as_array(&self) -> Option<&Vec<Self>> {
200        match self {
201            Self::Array(a) => Some(a),
202            _ => None,
203        }
204    }
205}
206impl ValueAsObject for Value {
207    type Object = Object;
208
209    #[cfg_attr(not(feature = "no-inline"), inline)]
210    fn as_object(&self) -> Option<&Object> {
211        match self {
212            Self::Object(m) => Some(m),
213            _ => None,
214        }
215    }
216}
217
218impl ValueIntoString for Value {
219    type String = String;
220
221    fn into_string(self) -> Option<<Value as ValueIntoString>::String> {
222        match self {
223            Self::String(s) => Some(s),
224            _ => None,
225        }
226    }
227}
228impl ValueIntoArray for Value {
229    type Array = Vec<Self>;
230
231    fn into_array(self) -> Option<<Value as ValueIntoArray>::Array> {
232        match self {
233            Self::Array(a) => Some(*a),
234            _ => None,
235        }
236    }
237}
238impl ValueIntoObject for Value {
239    type Object = Object;
240
241    fn into_object(self) -> Option<<Value as ValueIntoObject>::Object> {
242        match self {
243            Self::Object(a) => Some(*a),
244            _ => None,
245        }
246    }
247}
248
249#[cfg(not(tarpaulin_include))]
250impl fmt::Display for Value {
251    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
252        match self {
253            Self::Static(s) => s.fmt(f),
254            Self::String(s) => write!(f, "{s}"),
255            Self::Array(a) => write!(f, "{a:?}"),
256            Self::Object(o) => write!(f, "{o:?}"),
257        }
258    }
259}
260
261impl Index<&str> for Value {
262    type Output = Self;
263    #[cfg_attr(not(feature = "no-inline"), inline)]
264    fn index(&self, index: &str) -> &Self::Output {
265        self.get(index).expect("index out of bounds")
266    }
267}
268
269impl Index<usize> for Value {
270    type Output = Self;
271    #[cfg_attr(not(feature = "no-inline"), inline)]
272    fn index(&self, index: usize) -> &Self::Output {
273        self.get_idx(index).expect("index out of bounds")
274    }
275}
276
277impl IndexMut<&str> for Value {
278    #[cfg_attr(not(feature = "no-inline"), inline)]
279    fn index_mut(&mut self, index: &str) -> &mut Self::Output {
280        self.get_mut(index).expect("index out of bounds")
281    }
282}
283
284impl IndexMut<usize> for Value {
285    #[cfg_attr(not(feature = "no-inline"), inline)]
286    fn index_mut(&mut self, index: usize) -> &mut Self::Output {
287        self.get_idx_mut(index).expect("index out of bounds")
288    }
289}
290
291impl Default for Value {
292    #[cfg_attr(not(feature = "no-inline"), inline)]
293    fn default() -> Self {
294        Self::Static(StaticNode::Null)
295    }
296}
297
298struct OwnedDeserializer<'de> {
299    de: Deserializer<'de>,
300}
301
302impl<'de> OwnedDeserializer<'de> {
303    pub fn from_deserializer(de: Deserializer<'de>) -> Self {
304        Self { de }
305    }
306    #[cfg_attr(not(feature = "no-inline"), inline)]
307    pub fn parse(&mut self) -> Value {
308        match unsafe { self.de.next_() } {
309            Node::Static(s) => Value::Static(s),
310            Node::String(s) => Value::from(s),
311            Node::Array { len, count: _ } => self.parse_array(len),
312            Node::Object { len, count: _ } => self.parse_map(len),
313        }
314    }
315
316    #[cfg_attr(not(feature = "no-inline"), inline)]
317    fn parse_array(&mut self, len: usize) -> Value {
318        // Rust doesn't optimize the normal loop away here
319        // so we write our own avoiding the length
320        // checks during push
321        let mut res: Vec<Value> = Vec::with_capacity(len);
322        let res_ptr = res.as_mut_ptr();
323        unsafe {
324            for i in 0..len {
325                res_ptr.add(i).write(self.parse());
326            }
327            res.set_len(len);
328        }
329        Value::Array(Box::new(res))
330    }
331
332    #[cfg_attr(not(feature = "no-inline"), inline)]
333    fn parse_map(&mut self, len: usize) -> Value {
334        let mut res = Object::with_capacity_and_hasher(len, ObjectHasher::default());
335
336        for _ in 0..len {
337            if let Node::String(key) = unsafe { self.de.next_() } {
338                #[cfg(not(feature = "value-no-dup-keys"))]
339                unsafe {
340                    res.insert_nocheck(key.into(), self.parse());
341                };
342                #[cfg(feature = "value-no-dup-keys")]
343                res.insert(key.into(), self.parse());
344            } else {
345                unreachable!("parse_map: key needs to be a string");
346            }
347        }
348        Value::from(res)
349    }
350}
351
352#[cfg(test)]
353mod test {
354    #![allow(clippy::cognitive_complexity, clippy::ignored_unit_patterns)]
355    use super::*;
356
357    #[test]
358    fn object_access() {
359        let mut v = Value::null();
360        assert_eq!(v.insert("key", ()), Err(AccessError::NotAnObject));
361        assert_eq!(v.remove("key"), Err(AccessError::NotAnObject));
362        let mut v = Value::object();
363        assert_eq!(v.insert("key", 1), Ok(None));
364        assert_eq!(v["key"], 1);
365        assert_eq!(v.insert("key", 2), Ok(Some(Value::from(1))));
366        v["key"] = 3.into();
367        assert_eq!(v.remove("key"), Ok(Some(Value::from(3))));
368    }
369
370    #[test]
371    fn array_access() {
372        let mut v = Value::null();
373        assert_eq!(v.push("key"), Err(AccessError::NotAnArray));
374        assert_eq!(v.pop(), Err(AccessError::NotAnArray));
375        let mut v = Value::array();
376        assert_eq!(v.push(1), Ok(()));
377        assert_eq!(v.push(2), Ok(()));
378        assert_eq!(v[0], 1);
379        v[0] = 0.into();
380        v[1] = 1.into();
381        assert_eq!(v.pop(), Ok(Some(Value::from(1))));
382        assert_eq!(v.pop(), Ok(Some(Value::from(0))));
383        assert_eq!(v.pop(), Ok(None));
384    }
385
386    #[cfg(feature = "128bit")]
387    #[test]
388    fn conversions_i128() {
389        let v = Value::from(i128::MAX);
390        assert!(v.is_i128());
391        assert!(v.is_u128());
392        assert!(!v.is_i64());
393        assert!(!v.is_u64());
394        assert!(!v.is_i32());
395        assert!(!v.is_u32());
396        assert!(!v.is_i16());
397        assert!(!v.is_u16());
398        assert!(!v.is_i8());
399        assert!(!v.is_u8());
400        assert!(!v.is_f64());
401        assert!(!v.is_f32());
402        assert!(v.is_f64_castable());
403        let v = Value::from(i128::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    #[test]
419    fn conversions_i64() {
420        let v = Value::from(i64::MAX);
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        let v = Value::from(i64::MIN);
435        assert!(v.is_i128());
436        assert!(!v.is_u128());
437        assert!(v.is_i64());
438        assert!(!v.is_u64());
439        assert!(!v.is_i32());
440        assert!(!v.is_u32());
441        assert!(!v.is_i16());
442        assert!(!v.is_u16());
443        assert!(!v.is_i8());
444        assert!(!v.is_u8());
445        assert!(!v.is_f64());
446        assert!(!v.is_f32());
447        assert!(v.is_f64_castable());
448    }
449
450    #[test]
451    fn conversions_i32() {
452        let v = Value::from(i32::MAX);
453        assert!(v.is_i128());
454        assert!(v.is_u128());
455        assert!(v.is_i64());
456        assert!(v.is_u64());
457        assert!(v.is_i32());
458        assert!(v.is_u32());
459        assert!(!v.is_i16());
460        assert!(!v.is_u16());
461        assert!(!v.is_i8());
462        assert!(!v.is_u8());
463        assert!(!v.is_f64());
464        assert!(!v.is_f32());
465        assert!(v.is_f64_castable());
466        let v = Value::from(i32::MIN);
467        assert!(v.is_i128());
468        assert!(!v.is_u128());
469        assert!(v.is_i64());
470        assert!(!v.is_u64());
471        assert!(v.is_i32());
472        assert!(!v.is_u32());
473        assert!(!v.is_i16());
474        assert!(!v.is_u16());
475        assert!(!v.is_i8());
476        assert!(!v.is_u8());
477        assert!(!v.is_f64());
478        assert!(!v.is_f32());
479        assert!(v.is_f64_castable());
480    }
481
482    #[test]
483    fn conversions_i16() {
484        let v = Value::from(i16::MAX);
485        assert!(v.is_i128());
486        assert!(v.is_u128());
487        assert!(v.is_i64());
488        assert!(v.is_u64());
489        assert!(v.is_i32());
490        assert!(v.is_u32());
491        assert!(v.is_i16());
492        assert!(v.is_u16());
493        assert!(!v.is_i8());
494        assert!(!v.is_u8());
495        assert!(!v.is_f64());
496        assert!(!v.is_f32());
497        assert!(v.is_f64_castable());
498        let v = Value::from(i16::MIN);
499        assert!(v.is_i128());
500        assert!(!v.is_u128());
501        assert!(v.is_i64());
502        assert!(!v.is_u64());
503        assert!(v.is_i32());
504        assert!(!v.is_u32());
505        assert!(v.is_i16());
506        assert!(!v.is_u16());
507        assert!(!v.is_i8());
508        assert!(!v.is_u8());
509        assert!(!v.is_f64());
510        assert!(!v.is_f32());
511        assert!(v.is_f64_castable());
512        assert!(v.is_f64_castable());
513    }
514
515    #[test]
516    fn conversions_i8() {
517        let v = Value::from(i8::MAX);
518        assert!(v.is_i128());
519        assert!(v.is_u128());
520        assert!(v.is_i64());
521        assert!(v.is_u64());
522        assert!(v.is_i32());
523        assert!(v.is_u32());
524        assert!(v.is_i16());
525        assert!(v.is_u16());
526        assert!(v.is_i8());
527        assert!(v.is_u8());
528        assert!(!v.is_f64());
529        assert!(!v.is_f32());
530        assert!(v.is_f64_castable());
531        let v = Value::from(i8::MIN);
532        assert!(v.is_i128());
533        assert!(!v.is_u128());
534        assert!(v.is_i64());
535        assert!(!v.is_u64());
536        assert!(v.is_i32());
537        assert!(!v.is_u32());
538        assert!(v.is_i16());
539        assert!(!v.is_u16());
540        assert!(v.is_i8());
541        assert!(!v.is_u8());
542        assert!(!v.is_f64());
543        assert!(!v.is_f32());
544        assert!(v.is_f64_castable());
545    }
546
547    #[test]
548    fn conversions_usize() {
549        let v = Value::from(usize::MIN as u64);
550        assert!(v.is_i128());
551        assert!(v.is_u128());
552        assert!(v.is_i64());
553        assert!(v.is_u64());
554        assert!(v.is_usize());
555        assert!(v.is_i32());
556        assert!(v.is_u32());
557        assert!(v.is_i16());
558        assert!(v.is_u16());
559        assert!(v.is_i8());
560        assert!(v.is_u8());
561        assert!(!v.is_f64());
562        assert!(!v.is_f32());
563        assert!(!v.is_f64());
564        assert!(!v.is_f32());
565        assert!(v.is_f64_castable());
566    }
567
568    #[cfg(feature = "128bit")]
569    #[test]
570    fn conversions_u128() {
571        let v = Value::from(u128::MIN);
572        assert!(v.is_i128());
573        assert!(v.is_u128());
574        assert!(v.is_i64());
575        assert!(v.is_u64());
576        assert!(v.is_i32());
577        assert!(v.is_u32());
578        assert!(v.is_i16());
579        assert!(v.is_u16());
580        assert!(v.is_i8());
581        assert!(v.is_u8());
582        assert!(!v.is_f64());
583        assert!(!v.is_f32());
584        assert!(v.is_f64_castable());
585    }
586    #[test]
587    fn conversions_u64() {
588        let v = Value::from(u64::MIN);
589        assert!(v.is_i128());
590        assert!(v.is_u128());
591        assert!(v.is_i64());
592        assert!(v.is_u64());
593        assert!(v.is_i32());
594        assert!(v.is_u32());
595        assert!(v.is_i16());
596        assert!(v.is_u16());
597        assert!(v.is_i8());
598        assert!(v.is_u8());
599        assert!(!v.is_f64());
600        assert!(!v.is_f32());
601        assert!(v.is_f64_castable());
602    }
603
604    #[test]
605    fn conversions_u32() {
606        let v = Value::from(u32::MAX);
607        assert!(v.is_i128());
608        assert!(v.is_u128());
609        assert!(v.is_i64());
610        assert!(v.is_u64());
611        assert!(!v.is_i32());
612        assert!(v.is_u32());
613        assert!(!v.is_i16());
614        assert!(!v.is_u16());
615        assert!(!v.is_i8());
616        assert!(!v.is_u8());
617        assert!(!v.is_f64());
618        assert!(!v.is_f32());
619        assert!(v.is_f64_castable());
620    }
621
622    #[test]
623    fn conversions_u16() {
624        let v = Value::from(u16::MAX);
625        assert!(v.is_i128());
626        assert!(v.is_u128());
627        assert!(v.is_i64());
628        assert!(v.is_u64());
629        assert!(v.is_i32());
630        assert!(v.is_u32());
631        assert!(!v.is_i16());
632        assert!(v.is_u16());
633        assert!(!v.is_i8());
634        assert!(!v.is_u8());
635        assert!(!v.is_f64());
636        assert!(!v.is_f32());
637        assert!(v.is_f64_castable());
638    }
639
640    #[test]
641    fn conversions_u8() {
642        let v = Value::from(u8::MAX);
643        assert!(v.is_i128());
644        assert!(v.is_u128());
645        assert!(v.is_i64());
646        assert!(v.is_u64());
647        assert!(v.is_i32());
648        assert!(v.is_u32());
649        assert!(v.is_i16());
650        assert!(v.is_u16());
651        assert!(!v.is_i8());
652        assert!(v.is_u8());
653        assert!(!v.is_f64());
654        assert!(!v.is_f32());
655        assert!(v.is_f64_castable());
656    }
657
658    #[test]
659    fn conversions_f64() {
660        let v = Value::from(f64::MAX);
661        assert!(!v.is_i64());
662        assert!(!v.is_u64());
663        assert!(v.is_f64());
664        assert!(!v.is_f32());
665        assert!(v.is_f64_castable());
666        let v = Value::from(f64::MIN);
667        assert!(!v.is_i64());
668        assert!(!v.is_u64());
669        assert!(v.is_f64());
670        assert!(!v.is_f32());
671        assert!(v.is_f64_castable());
672        let v = Value::from("not a f64");
673        assert!(!v.is_f64_castable());
674    }
675
676    #[test]
677    fn conversions_f32() {
678        let v = Value::from(f32::MAX);
679        assert!(!v.is_i64());
680        assert!(!v.is_u64());
681        assert!(v.is_f64());
682        assert!(v.is_f32());
683        assert!(v.is_f64_castable());
684        let v = Value::from(f32::MIN);
685        assert!(!v.is_i64());
686        assert!(!v.is_u64());
687        assert!(v.is_f64());
688        assert!(v.is_f32());
689        assert!(v.is_f64_castable());
690    }
691
692    #[test]
693    fn conversions_array() {
694        let v = Value::from(vec![true]);
695        assert!(v.is_array());
696        assert_eq!(v.value_type(), ValueType::Array);
697        let v = Value::from("no array");
698        assert!(!v.is_array());
699    }
700
701    #[test]
702    fn conversions_bool() {
703        let v = Value::from(true);
704        assert!(v.is_bool());
705        assert_eq!(v.value_type(), ValueType::Bool);
706        let v = Value::from("no bool");
707        assert!(!v.is_bool());
708    }
709
710    #[test]
711    fn conversions_float() {
712        let v = Value::from(42.0);
713        assert!(v.is_f64());
714        assert_eq!(v.value_type(), ValueType::F64);
715        let v = Value::from("no float");
716        assert!(!v.is_f64());
717    }
718
719    #[test]
720    fn conversions_int() {
721        let v = Value::from(-42);
722        assert!(v.is_i64());
723        assert_eq!(v.value_type(), ValueType::I64);
724        #[cfg(feature = "128bit")]
725        {
726            let v = Value::from(-42_i128);
727            assert!(v.is_i64());
728            assert!(v.is_i128());
729            assert_eq!(v.value_type(), ValueType::I128);
730        }
731        let v = Value::from("no i64");
732        assert!(!v.is_i64());
733        #[cfg(feature = "128bit")]
734        assert!(!v.is_i128());
735    }
736
737    #[test]
738    fn conversions_uint() {
739        let v = Value::from(42_u64);
740        assert!(v.is_u64());
741        assert_eq!(v.value_type(), ValueType::U64);
742        #[cfg(feature = "128bit")]
743        {
744            let v = Value::from(42_u128);
745            assert!(v.is_u64());
746            assert!(v.is_u128());
747            assert_eq!(v.value_type(), ValueType::U128);
748        }
749        let v = Value::from("no u64");
750        assert!(!v.is_u64());
751        #[cfg(feature = "128bit")]
752        assert!(!v.is_u128());
753    }
754
755    #[test]
756    fn conversions_null() {
757        let v = Value::from(());
758        assert!(v.is_null());
759        assert_eq!(v.value_type(), ValueType::Null);
760        let v = Value::from("no null");
761        assert!(!v.is_null());
762    }
763
764    #[test]
765    fn conversions_object() {
766        let v = Value::from(Object::with_capacity_and_hasher(0, ObjectHasher::default()));
767        assert!(v.is_object());
768        assert_eq!(v.value_type(), ValueType::Object);
769        let v = Value::from("no object");
770        assert!(!v.is_object());
771    }
772
773    #[test]
774    fn conversions_str() {
775        let v = Value::from("bla");
776        assert!(v.is_str());
777        assert_eq!(v.value_type(), ValueType::String);
778        let v = Value::from(42);
779        assert!(!v.is_str());
780    }
781
782    #[test]
783    fn default() {
784        assert_eq!(Value::default(), Value::null());
785    }
786
787    #[cfg(not(target_arch = "wasm32"))]
788    use proptest::prelude::*;
789    #[cfg(not(target_arch = "wasm32"))]
790    fn arb_value() -> BoxedStrategy<Value> {
791        let leaf = prop_oneof![
792            Just(Value::Static(StaticNode::Null)),
793            any::<bool>()
794                .prop_map(StaticNode::Bool)
795                .prop_map(Value::Static),
796            any::<i64>()
797                .prop_map(StaticNode::I64)
798                .prop_map(Value::Static),
799            any::<f64>()
800                .prop_map(StaticNode::from)
801                .prop_map(Value::Static),
802            ".*".prop_map(Value::from),
803        ];
804        leaf.prop_recursive(
805            8,   // 8 levels deep
806            256, // Shoot for maximum size of 256 nodes
807            10,  // We put up to 10 items per collection
808            |inner| {
809                prop_oneof![
810                    // Take the inner strategy and make the two recursive cases.
811                    prop::collection::vec(inner.clone(), 0..10).prop_map(Value::from),
812                    prop::collection::hash_map(".*", inner, 0..10)
813                        .prop_map(|m| m.into_iter().collect()),
814                ]
815            },
816        )
817        .boxed()
818    }
819
820    #[cfg(not(target_arch = "wasm32"))]
821    proptest! {
822        #![proptest_config(ProptestConfig {
823            .. ProptestConfig::default()
824        })]
825
826        #[test]
827        fn prop_to_owned(owned in arb_value()) {
828            use crate::BorrowedValue;
829            let borrowed: BorrowedValue = owned.clone().into();
830            prop_assert_eq!(owned, borrowed);
831        }
832
833        #[test]
834        fn prop_serialize_deserialize(owned in arb_value()) {
835            let mut string = owned.encode();
836            let bytes = unsafe{ string.as_bytes_mut()};
837            let decoded = to_value(bytes).expect("Failed to decode");
838            prop_assert_eq!(owned, decoded);
839        }
840        #[test]
841        #[allow(clippy::float_cmp)]
842        fn prop_f64_cmp(f in proptest::num::f64::NORMAL) {
843            let v: Value = f.into();
844            prop_assert_eq!(v, f);
845
846        }
847
848        #[test]
849        #[allow(clippy::float_cmp)]
850        fn prop_f32_cmp(f in proptest::num::f32::NORMAL) {
851            let v: Value = f.into();
852            prop_assert_eq!(v, f);
853
854        }
855        #[test]
856        fn prop_i64_cmp(f in proptest::num::i64::ANY) {
857            let v: Value = f.into();
858            prop_assert_eq!(v, f);
859        }
860        #[test]
861        fn prop_i32_cmp(f in proptest::num::i32::ANY) {
862            let v: Value = f.into();
863            prop_assert_eq!(v, f);
864        }
865        #[test]
866        fn prop_i16_cmp(f in proptest::num::i16::ANY) {
867            let v: Value = f.into();
868            prop_assert_eq!(v, f);
869        }
870        #[test]
871        fn prop_i8_cmp(f in proptest::num::i8::ANY) {
872            let v: Value = f.into();
873            prop_assert_eq!(v, f);
874        }
875        #[test]
876        fn prop_u64_cmp(f in proptest::num::u64::ANY) {
877            let v: Value = f.into();
878            prop_assert_eq!(v, f);
879        }
880
881        #[test]
882        fn prop_usize_cmp(f in proptest::num::usize::ANY) {
883            let v: Value = f.into();
884            prop_assert_eq!(v, f);
885        }
886         #[test]
887        fn prop_u32_cmp(f in proptest::num::u32::ANY) {
888            let v: Value = f.into();
889            prop_assert_eq!(v, f);
890        }
891        #[test]
892        fn prop_u16_cmp(f in proptest::num::u16::ANY) {
893            let v: Value = f.into();
894            prop_assert_eq!(v, f);
895        }
896        #[test]
897        fn prop_u8_cmp(f in proptest::num::u8::ANY) {
898            let v: Value = f.into();
899            prop_assert_eq!(v.clone(), &f);
900            prop_assert_eq!(v, f);
901        }
902        #[test]
903        fn prop_string_cmp(f in ".*") {
904            let v: Value = f.clone().into();
905            prop_assert_eq!(v.clone(), f.as_str());
906            prop_assert_eq!(v, f);
907        }
908
909    }
910    #[test]
911    fn test_union_cmp() {
912        let v: Value = ().into();
913        assert_eq!(v, ());
914    }
915    #[test]
916    #[allow(clippy::bool_assert_comparison)]
917    fn test_bool_cmp() {
918        let v: Value = true.into();
919        assert_eq!(v, true);
920        let v: Value = false.into();
921        assert_eq!(v, false);
922    }
923    #[test]
924    fn test_slice_cmp() {
925        use std::iter::FromIterator;
926        let v: Value = Value::from_iter(vec!["a", "b"]);
927        assert_eq!(v, &["a", "b"][..]);
928    }
929    #[test]
930    fn test_hashmap_cmp() {
931        use std::iter::FromIterator;
932        let v: Value = Value::from_iter(vec![("a", 1)]);
933        assert_eq!(
934            v,
935            [("a", 1)]
936                .iter()
937                .copied()
938                .collect::<std::collections::HashMap<&str, i32>>()
939        );
940    }
941    #[test]
942    fn test_option_from() {
943        let v: Option<u8> = None;
944        let v: Value = v.into();
945        assert_eq!(v, ());
946        let v: Option<u8> = Some(42);
947        let v: Value = v.into();
948        assert_eq!(v, 42);
949    }
950}