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