1mod cmp;
24mod from;
25mod serialize;
26
27use super::ObjectHasher;
28use crate::{cow::Cow, safer_unchecked::GetSaferUnchecked as _};
29use crate::{prelude::*, Buffers};
30use crate::{Deserializer, Node, Result};
31use halfbrown::HashMap;
32use std::fmt;
33use std::ops::{Index, IndexMut};
34
35pub type Object<'value> = HashMap<Cow<'value, str>, Value<'value>, ObjectHasher>;
37pub type Array<'value> = Vec<Value<'value>>;
39
40pub fn to_value(s: &mut [u8]) -> Result<Value> {
50 match Deserializer::from_slice(s) {
51 Ok(de) => Ok(BorrowDeserializer::from_deserializer(de).parse()),
52 Err(e) => Err(e),
53 }
54}
55
56pub fn to_value_with_buffers<'value>(
68 s: &'value mut [u8],
69 buffers: &mut Buffers,
70) -> Result<Value<'value>> {
71 match Deserializer::from_slice_with_buffers(s, buffers) {
72 Ok(de) => Ok(BorrowDeserializer::from_deserializer(de).parse()),
73 Err(e) => Err(e),
74 }
75}
76
77#[derive(Debug, Clone)]
80#[cfg_attr(feature = "ordered-float", derive(Eq))]
81pub enum Value<'value> {
82 Static(StaticNode),
84 String(Cow<'value, str>),
86 Array(Box<Vec<Value<'value>>>),
88 Object(Box<Object<'value>>),
90}
91
92impl<'value> Value<'value> {
93 fn as_static(&self) -> Option<StaticNode> {
94 match self {
95 Self::Static(s) => Some(*s),
96 _ => None,
97 }
98 }
99
100 #[cfg_attr(not(feature = "no-inline"), inline)]
104 #[must_use]
105 pub fn into_static(self) -> Value<'static> {
106 match self {
107 Self::String(s) => unsafe {
114 std::mem::transmute::<Value<'value>, Value<'static>>(Self::String(Cow::from(
115 s.into_owned(),
116 )))
117 },
118 Self::Array(arr) => arr.into_iter().map(Value::into_static).collect(),
120 Self::Object(obj) => obj
122 .into_iter()
123 .map(|(k, v)| (Cow::from(k.into_owned()), v.into_static()))
124 .collect(),
125
126 Value::Static(s) => Value::Static(s),
128 }
129 }
130
131 #[cfg_attr(not(feature = "no-inline"), inline)]
134 #[must_use]
135 pub fn clone_static(&self) -> Value<'static> {
136 match self {
137 Self::String(s) => unsafe {
144 std::mem::transmute::<Value<'value>, Value<'static>>(Self::String(Cow::from(
145 s.to_string(),
146 )))
147 },
148 Self::Array(arr) => arr.iter().cloned().map(Value::into_static).collect(),
150 Self::Object(obj) => obj
152 .iter()
153 .map(|(k, v)| (Cow::from(k.to_string()), v.clone_static()))
154 .collect(),
155
156 Value::Static(s) => Value::Static(*s),
158 }
159 }
160}
161
162impl<'value> ValueBuilder<'value> for Value<'value> {
163 #[cfg_attr(not(feature = "no-inline"), inline)]
164 #[must_use]
165 fn null() -> Self {
166 Self::Static(StaticNode::Null)
167 }
168 #[cfg_attr(not(feature = "no-inline"), inline)]
169 #[must_use]
170 fn array_with_capacity(capacity: usize) -> Self {
171 Self::Array(Box::new(Vec::with_capacity(capacity)))
172 }
173 #[cfg_attr(not(feature = "no-inline"), inline)]
174 #[must_use]
175 fn object_with_capacity(capacity: usize) -> Self {
176 Self::Object(Box::new(Object::with_capacity_and_hasher(
177 capacity,
178 ObjectHasher::default(),
179 )))
180 }
181}
182
183impl<'value> ValueAsMutArray for Value<'value> {
184 type Array = Array<'value>;
185 #[cfg_attr(not(feature = "no-inline"), inline)]
186 #[must_use]
187 fn as_array_mut(&mut self) -> Option<&mut Vec<Value<'value>>> {
188 match self {
189 Self::Array(a) => Some(a),
190 _ => None,
191 }
192 }
193}
194impl<'value> ValueAsMutObject for Value<'value> {
195 type Object = Object<'value>;
196 #[cfg_attr(not(feature = "no-inline"), inline)]
215 #[must_use]
216 fn as_object_mut(&mut self) -> Option<&mut Object<'value>> {
217 match self {
218 Self::Object(m) => Some(m),
219 _ => None,
220 }
221 }
222}
223
224impl<'value> TypedValue for Value<'value> {
225 #[cfg_attr(not(feature = "no-inline"), inline)]
226 #[must_use]
227 fn value_type(&self) -> ValueType {
228 match self {
229 Self::Static(s) => s.value_type(),
230 Self::String(_) => ValueType::String,
231 Self::Array(_) => ValueType::Array,
232 Self::Object(_) => ValueType::Object,
233 }
234 }
235}
236impl<'value> ValueAsScalar for Value<'value> {
237 #[cfg_attr(not(feature = "no-inline"), inline)]
238 #[must_use]
239 fn as_null(&self) -> Option<()> {
240 self.as_static()?.as_null()
241 }
242
243 #[cfg_attr(not(feature = "no-inline"), inline)]
244 #[must_use]
245 fn as_bool(&self) -> Option<bool> {
246 self.as_static()?.as_bool()
247 }
248
249 #[cfg_attr(not(feature = "no-inline"), inline)]
250 #[must_use]
251 fn as_i64(&self) -> Option<i64> {
252 self.as_static()?.as_i64()
253 }
254
255 #[cfg_attr(not(feature = "no-inline"), inline)]
256 #[must_use]
257 fn as_i128(&self) -> Option<i128> {
258 self.as_static()?.as_i128()
259 }
260
261 #[cfg_attr(not(feature = "no-inline"), inline)]
262 #[must_use]
263 fn as_u64(&self) -> Option<u64> {
264 self.as_static()?.as_u64()
265 }
266
267 #[cfg_attr(not(feature = "no-inline"), inline)]
268 #[must_use]
269 fn as_u128(&self) -> Option<u128> {
270 self.as_static()?.as_u128()
271 }
272
273 #[cfg_attr(not(feature = "no-inline"), inline)]
274 #[must_use]
275 fn as_f64(&self) -> Option<f64> {
276 self.as_static()?.as_f64()
277 }
278
279 #[cfg_attr(not(feature = "no-inline"), inline)]
280 #[must_use]
281 fn cast_f64(&self) -> Option<f64> {
282 self.as_static()?.cast_f64()
283 }
284
285 #[cfg_attr(not(feature = "no-inline"), inline)]
286 #[must_use]
287 fn as_str(&self) -> Option<&str> {
288 use std::borrow::Borrow;
289 match self {
290 Self::String(s) => Some(s.borrow()),
291 _ => None,
292 }
293 }
294}
295impl<'value> ValueAsArray for Value<'value> {
296 type Array = Array<'value>;
297
298 #[cfg_attr(not(feature = "no-inline"), inline)]
299 #[must_use]
300 fn as_array(&self) -> Option<&Vec<Value<'value>>> {
301 match self {
302 Self::Array(a) => Some(a),
303 _ => None,
304 }
305 }
306}
307
308impl<'value> ValueAsObject for Value<'value> {
309 type Object = Object<'value>;
310
311 #[cfg_attr(not(feature = "no-inline"), inline)]
312 #[must_use]
313 fn as_object(&self) -> Option<&Object<'value>> {
314 match self {
315 Self::Object(m) => Some(m),
316 _ => None,
317 }
318 }
319}
320
321impl<'value> ValueIntoString for Value<'value> {
322 type String = Cow<'value, str>;
323
324 fn into_string(self) -> Option<<Self as ValueIntoString>::String> {
325 match self {
326 Self::String(s) => Some(s),
327 _ => None,
328 }
329 }
330}
331
332impl<'value> ValueIntoArray for Value<'value> {
333 type Array = Array<'value>;
334
335 fn into_array(self) -> Option<<Self as ValueIntoArray>::Array> {
336 match self {
337 Self::Array(a) => Some(*a),
338 _ => None,
339 }
340 }
341}
342
343impl<'value> ValueIntoObject for Value<'value> {
344 type Object = Object<'value>;
345
346 fn into_object(self) -> Option<<Self as ValueIntoObject>::Object> {
347 match self {
348 Self::Object(a) => Some(*a),
349 _ => None,
350 }
351 }
352}
353
354#[cfg(not(tarpaulin_include))]
355impl<'value> fmt::Display for Value<'value> {
356 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
357 match self {
358 Self::Static(s) => write!(f, "{s}"),
359 Self::String(s) => write!(f, "{s}"),
360 Self::Array(a) => write!(f, "{a:?}"),
361 Self::Object(o) => write!(f, "{o:?}"),
362 }
363 }
364}
365
366impl<'value> Index<&str> for Value<'value> {
367 type Output = Value<'value>;
368 #[cfg_attr(not(feature = "no-inline"), inline)]
369 #[must_use]
370 fn index(&self, index: &str) -> &Self::Output {
371 self.get(index).expect("index out of bounds")
372 }
373}
374
375impl<'value> Index<usize> for Value<'value> {
376 type Output = Value<'value>;
377 #[cfg_attr(not(feature = "no-inline"), inline)]
378 #[must_use]
379 fn index(&self, index: usize) -> &Self::Output {
380 self.get_idx(index).expect("index out of bounds")
381 }
382}
383
384impl<'value> IndexMut<&str> for Value<'value> {
385 #[cfg_attr(not(feature = "no-inline"), inline)]
386 #[must_use]
387 fn index_mut(&mut self, index: &str) -> &mut Self::Output {
388 self.get_mut(index).expect("index out of bounds")
389 }
390}
391
392impl<'value> IndexMut<usize> for Value<'value> {
393 #[cfg_attr(not(feature = "no-inline"), inline)]
394 #[must_use]
395 fn index_mut(&mut self, index: usize) -> &mut Self::Output {
396 self.get_idx_mut(index).expect("index out of bounds")
397 }
398}
399
400impl<'value> Default for Value<'value> {
401 #[cfg_attr(not(feature = "no-inline"), inline)]
402 #[must_use]
403 fn default() -> Self {
404 Self::Static(StaticNode::Null)
405 }
406}
407
408pub(super) struct BorrowDeserializer<'de>(Deserializer<'de>);
409
410impl<'de> BorrowDeserializer<'de> {
411 pub fn from_deserializer(de: Deserializer<'de>) -> Self {
412 Self(de)
413 }
414
415 #[cfg_attr(not(feature = "no-inline"), inline)]
416 pub fn parse(&mut self) -> Value<'de> {
417 match unsafe { self.0.next_() } {
418 Node::Static(s) => Value::Static(s),
419 Node::String(s) => Value::from(s),
420 Node::Array { len, count: _ } => self.parse_array(len),
421 Node::Object { len, count: _ } => self.parse_map(len),
422 }
423 }
424
425 #[cfg_attr(not(feature = "no-inline"), inline)]
426 fn parse_array(&mut self, len: usize) -> Value<'de> {
427 let mut res: Vec<Value<'de>> = Vec::with_capacity(len);
431 let res_ptr = res.as_mut_ptr();
432 unsafe {
433 for i in 0..len {
434 res_ptr.add(i).write(self.parse());
435 }
436 res.set_len(len);
437 }
438 Value::Array(Box::new(res))
439 }
440
441 #[cfg_attr(not(feature = "no-inline"), inline)]
442 fn parse_map(&mut self, len: usize) -> Value<'de> {
443 let mut res = Object::with_capacity_and_hasher(len, ObjectHasher::default());
444
445 for _ in 0..len {
448 if let Node::String(key) = unsafe { self.0.next_() } {
449 #[cfg(not(feature = "value-no-dup-keys"))]
450 res.insert_nocheck(key.into(), self.parse());
451 #[cfg(feature = "value-no-dup-keys")]
452 res.insert(key.into(), self.parse());
453 } else {
454 unreachable!();
455 }
456 }
457 Value::from(res)
458 }
459}
460pub(super) struct BorrowSliceDeserializer<'tape, 'de> {
461 tape: &'tape [Node<'de>],
462 idx: usize,
463}
464impl<'tape, 'de> BorrowSliceDeserializer<'tape, 'de> {
465 pub fn from_tape(de: &'tape [Node<'de>]) -> Self {
466 Self { tape: de, idx: 0 }
467 }
468 #[cfg_attr(not(feature = "no-inline"), inline)]
469 pub unsafe fn next_(&mut self) -> Node<'de> {
470 let r = unsafe { *self.tape.get_kinda_unchecked(self.idx) };
471 self.idx += 1;
472 r
473 }
474
475 #[cfg_attr(not(feature = "no-inline"), inline)]
476 pub fn parse(&mut self) -> Value<'de> {
477 match unsafe { self.next_() } {
478 Node::Static(s) => Value::Static(s),
479 Node::String(s) => Value::from(s),
480 Node::Array { len, count: _ } => self.parse_array(len),
481 Node::Object { len, count: _ } => self.parse_map(len),
482 }
483 }
484
485 #[cfg_attr(not(feature = "no-inline"), inline)]
486 fn parse_array(&mut self, len: usize) -> Value<'de> {
487 let mut res: Vec<Value<'de>> = Vec::with_capacity(len);
491 let res_ptr = res.as_mut_ptr();
492 unsafe {
493 for i in 0..len {
494 res_ptr.add(i).write(self.parse());
495 }
496 res.set_len(len);
497 }
498 Value::Array(Box::new(res))
499 }
500
501 #[cfg_attr(not(feature = "no-inline"), inline)]
502 fn parse_map(&mut self, len: usize) -> Value<'de> {
503 let mut res = Object::with_capacity_and_hasher(len, ObjectHasher::default());
504
505 for _ in 0..len {
508 if let Node::String(key) = unsafe { self.next_() } {
509 #[cfg(not(feature = "value-no-dup-keys"))]
510 res.insert_nocheck(key.into(), self.parse());
511 #[cfg(feature = "value-no-dup-keys")]
512 res.insert(key.into(), self.parse());
513 } else {
514 unreachable!();
515 }
516 }
517 Value::from(res)
518 }
519}
520
521#[cfg(test)]
522mod test {
523 #![allow(clippy::ignored_unit_patterns)]
524 #![allow(clippy::cognitive_complexity)]
525 use super::*;
526
527 #[test]
528 fn object_access() {
529 let mut v = Value::null();
530 assert_eq!(v.insert("key", ()), Err(AccessError::NotAnObject));
531 assert_eq!(v.remove("key"), Err(AccessError::NotAnObject));
532 let mut v = Value::object();
533 assert_eq!(v.insert("key", 1), Ok(None));
534 assert_eq!(v["key"], 1);
535 assert_eq!(v.insert("key", 2), Ok(Some(Value::from(1))));
536 v["key"] = 3.into();
537 assert_eq!(v.remove("key"), Ok(Some(Value::from(3))));
538 }
539
540 #[test]
541 fn array_access() {
542 let mut v = Value::null();
543 assert_eq!(v.push("key"), Err(AccessError::NotAnArray));
544 assert_eq!(v.pop(), Err(AccessError::NotAnArray));
545 let mut v = Value::array();
546 assert_eq!(v.push(1), Ok(()));
547 assert_eq!(v.push(2), Ok(()));
548 assert_eq!(v[0], 1);
549 v[0] = 0.into();
550 v[1] = 1.into();
551 assert_eq!(v.pop(), Ok(Some(Value::from(1))));
552 assert_eq!(v.pop(), Ok(Some(Value::from(0))));
553 assert_eq!(v.pop(), Ok(None));
554 }
555
556 #[cfg(feature = "128bit")]
557 #[test]
558 fn conversions_i128() {
559 let v = Value::from(i128::MAX);
560 assert!(v.is_i128());
561 assert!(v.is_u128());
562 assert!(!v.is_i64());
563 assert!(!v.is_u64());
564 assert!(!v.is_i32());
565 assert!(!v.is_u32());
566 assert!(!v.is_i16());
567 assert!(!v.is_u16());
568 assert!(!v.is_i8());
569 assert!(!v.is_u8());
570 assert!(!v.is_f64());
571 assert!(!v.is_f32());
572 assert!(v.is_f64_castable());
573 let v = Value::from(i128::MIN);
574 assert!(v.is_i128());
575 assert!(!v.is_u128());
576 assert!(!v.is_i64());
577 assert!(!v.is_u64());
578 assert!(!v.is_i32());
579 assert!(!v.is_u32());
580 assert!(!v.is_i16());
581 assert!(!v.is_u16());
582 assert!(!v.is_i8());
583 assert!(!v.is_u8());
584 assert!(!v.is_f64());
585 assert!(!v.is_f32());
586 assert!(v.is_f64_castable());
587 }
588
589 #[test]
590 fn conversions_i64() {
591 let v = Value::from(i64::MAX);
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 let v = Value::from(i64::MIN);
606 assert!(v.is_i128());
607 assert!(!v.is_u128());
608 assert!(v.is_i64());
609 assert!(!v.is_u64());
610 assert!(!v.is_i32());
611 assert!(!v.is_u32());
612 assert!(!v.is_i16());
613 assert!(!v.is_u16());
614 assert!(!v.is_i8());
615 assert!(!v.is_u8());
616 assert!(!v.is_f64());
617 assert!(!v.is_f32());
618 assert!(v.is_f64_castable());
619 }
620
621 #[test]
622 fn conversions_i32() {
623 let v = Value::from(i32::MAX);
624 assert!(v.is_i128());
625 assert!(v.is_u128());
626 assert!(v.is_i64());
627 assert!(v.is_u64());
628 assert!(v.is_i32());
629 assert!(v.is_u32());
630 assert!(!v.is_i16());
631 assert!(!v.is_u16());
632 assert!(!v.is_i8());
633 assert!(!v.is_u8());
634 assert!(!v.is_f64());
635 assert!(!v.is_f32());
636 assert!(v.is_f64_castable());
637 let v = Value::from(i32::MIN);
638 assert!(v.is_i128());
639 assert!(!v.is_u128());
640 assert!(v.is_i64());
641 assert!(!v.is_u64());
642 assert!(v.is_i32());
643 assert!(!v.is_u32());
644 assert!(!v.is_i16());
645 assert!(!v.is_u16());
646 assert!(!v.is_i8());
647 assert!(!v.is_u8());
648 assert!(!v.is_f64());
649 assert!(!v.is_f32());
650 assert!(v.is_f64_castable());
651 }
652
653 #[test]
654 fn conversions_i16() {
655 let v = Value::from(i16::MAX);
656 assert!(v.is_i128());
657 assert!(v.is_u128());
658 assert!(v.is_i64());
659 assert!(v.is_u64());
660 assert!(v.is_i32());
661 assert!(v.is_u32());
662 assert!(v.is_i16());
663 assert!(v.is_u16());
664 assert!(!v.is_i8());
665 assert!(!v.is_u8());
666 assert!(!v.is_f64());
667 assert!(!v.is_f32());
668 assert!(v.is_f64_castable());
669 let v = Value::from(i16::MIN);
670 assert!(v.is_i128());
671 assert!(!v.is_u128());
672 assert!(v.is_i64());
673 assert!(!v.is_u64());
674 assert!(v.is_i32());
675 assert!(!v.is_u32());
676 assert!(v.is_i16());
677 assert!(!v.is_u16());
678 assert!(!v.is_i8());
679 assert!(!v.is_u8());
680 assert!(!v.is_f64());
681 assert!(!v.is_f32());
682 assert!(v.is_f64_castable());
683 assert!(v.is_f64_castable());
684 }
685
686 #[test]
687 fn conversions_i8() {
688 let v = Value::from(i8::MAX);
689 assert!(v.is_i128());
690 assert!(v.is_u128());
691 assert!(v.is_i64());
692 assert!(v.is_u64());
693 assert!(v.is_i32());
694 assert!(v.is_u32());
695 assert!(v.is_i16());
696 assert!(v.is_u16());
697 assert!(v.is_i8());
698 assert!(v.is_u8());
699 assert!(!v.is_f64());
700 assert!(!v.is_f32());
701 assert!(v.is_f64_castable());
702 let v = Value::from(i8::MIN);
703 assert!(v.is_i128());
704 assert!(!v.is_u128());
705 assert!(v.is_i64());
706 assert!(!v.is_u64());
707 assert!(v.is_i32());
708 assert!(!v.is_u32());
709 assert!(v.is_i16());
710 assert!(!v.is_u16());
711 assert!(v.is_i8());
712 assert!(!v.is_u8());
713 assert!(!v.is_f64());
714 assert!(!v.is_f32());
715 assert!(v.is_f64_castable());
716 }
717
718 #[test]
719 fn conversions_usize() {
720 let v = Value::from(usize::MIN as u64);
721 assert!(v.is_i128());
722 assert!(v.is_u128());
723 assert!(v.is_i64());
724 assert!(v.is_u64());
725 assert!(v.is_usize());
726 assert!(v.is_i32());
727 assert!(v.is_u32());
728 assert!(v.is_i16());
729 assert!(v.is_u16());
730 assert!(v.is_i8());
731 assert!(v.is_u8());
732 assert!(!v.is_f64());
733 assert!(!v.is_f32());
734 assert!(!v.is_f64());
735 assert!(!v.is_f32());
736 assert!(v.is_f64_castable());
737 }
738
739 #[cfg(feature = "128bit")]
740 #[test]
741 fn conversions_u128() {
742 let v = Value::from(u128::MIN);
743 assert!(v.is_i128());
744 assert!(v.is_u128());
745 assert!(v.is_i64());
746 assert!(v.is_u64());
747 assert!(v.is_i32());
748 assert!(v.is_u32());
749 assert!(v.is_i16());
750 assert!(v.is_u16());
751 assert!(v.is_i8());
752 assert!(v.is_u8());
753 assert!(!v.is_f64());
754 assert!(!v.is_f32());
755 assert!(v.is_f64_castable());
756 }
757
758 #[test]
759 fn conversions_u64() {
760 let v = Value::from(u64::MIN);
761 assert!(v.is_i128());
762 assert!(v.is_u128());
763 assert!(v.is_i64());
764 assert!(v.is_u64());
765 assert!(v.is_i32());
766 assert!(v.is_u32());
767 assert!(v.is_i16());
768 assert!(v.is_u16());
769 assert!(v.is_i8());
770 assert!(v.is_u8());
771 assert!(!v.is_f64());
772 assert!(!v.is_f32());
773 assert!(v.is_f64_castable());
774 }
775
776 #[test]
777 fn conversions_u32() {
778 let v = Value::from(u32::MAX);
779 assert!(v.is_i128());
780 assert!(v.is_u128());
781 assert!(v.is_i64());
782 assert!(v.is_u64());
783 assert!(!v.is_i32());
784 assert!(v.is_u32());
785 assert!(!v.is_i16());
786 assert!(!v.is_u16());
787 assert!(!v.is_i8());
788 assert!(!v.is_u8());
789 assert!(!v.is_f64());
790 assert!(!v.is_f32());
791 assert!(v.is_f64_castable());
792 }
793
794 #[test]
795 fn conversions_u16() {
796 let v = Value::from(u16::MAX);
797 assert!(v.is_i128());
798 assert!(v.is_u128());
799 assert!(v.is_i64());
800 assert!(v.is_u64());
801 assert!(v.is_i32());
802 assert!(v.is_u32());
803 assert!(!v.is_i16());
804 assert!(v.is_u16());
805 assert!(!v.is_i8());
806 assert!(!v.is_u8());
807 assert!(!v.is_f64());
808 assert!(!v.is_f32());
809 assert!(v.is_f64_castable());
810 }
811
812 #[test]
813 fn conversions_u8() {
814 let v = Value::from(u8::MAX);
815 assert!(v.is_i128());
816 assert!(v.is_u128());
817 assert!(v.is_i64());
818 assert!(v.is_u64());
819 assert!(v.is_i32());
820 assert!(v.is_u32());
821 assert!(v.is_i16());
822 assert!(v.is_u16());
823 assert!(!v.is_i8());
824 assert!(v.is_u8());
825 assert!(!v.is_f64());
826 assert!(!v.is_f32());
827 assert!(v.is_f64_castable());
828 }
829
830 #[test]
831 fn conversions_f64() {
832 let v = Value::from(f64::MAX);
833 assert!(!v.is_i64());
834 assert!(!v.is_u64());
835 assert!(v.is_f64());
836 assert!(!v.is_f32());
837 assert!(v.is_f64_castable());
838 let v = Value::from(f64::MIN);
839 assert!(!v.is_i64());
840 assert!(!v.is_u64());
841 assert!(v.is_f64());
842 assert!(!v.is_f32());
843 assert!(v.is_f64_castable());
844 let v = Value::from("not a f64");
845 assert!(!v.is_f64_castable());
846 }
847
848 #[test]
849 fn conversions_f32() {
850 let v = Value::from(f32::MAX);
851 assert!(!v.is_i64());
852 assert!(!v.is_u64());
853 assert!(v.is_f64());
854 assert!(v.is_f32());
855 assert!(v.is_f64_castable());
856 let v = Value::from(f32::MIN);
857 assert!(!v.is_i64());
858 assert!(!v.is_u64());
859 assert!(v.is_f64());
860 assert!(v.is_f32());
861 assert!(v.is_f64_castable());
862 }
863
864 #[test]
865 fn conversions_array() {
866 let v = Value::from(vec![true]);
867 assert!(v.is_array());
868 assert_eq!(v.value_type(), ValueType::Array);
869 let v = Value::from("no array");
870 assert!(!v.is_array());
871 }
872
873 #[test]
874 fn conversions_bool() {
875 let v = Value::from(true);
876 assert!(v.is_bool());
877 assert_eq!(v.value_type(), ValueType::Bool);
878 let v = Value::from("no bool");
879 assert!(!v.is_bool());
880 }
881
882 #[test]
883 fn conversions_float() {
884 let v = Value::from(42.0);
885 assert!(v.is_f64());
886 assert_eq!(v.value_type(), ValueType::F64);
887 let v = Value::from("no float");
888 assert!(!v.is_f64());
889 }
890
891 #[test]
892 fn conversions_int() {
893 let v = Value::from(-42);
894 assert!(v.is_i64());
895 assert_eq!(v.value_type(), ValueType::I64);
896 #[cfg(feature = "128bit")]
897 {
898 let v = Value::from(-42_i128);
899 assert!(v.is_i64());
900 assert!(v.is_i128());
901 assert_eq!(v.value_type(), ValueType::I128);
902 }
903 let v = Value::from("no i64");
904 assert!(!v.is_i64());
905 assert!(!v.is_i128());
906 }
907
908 #[test]
909 fn conversions_uint() {
910 let v = Value::from(42_u64);
911 assert!(v.is_u64());
912 assert_eq!(v.value_type(), ValueType::U64);
913 #[cfg(feature = "128bit")]
914 {
915 let v = Value::from(42_u128);
916 assert!(v.is_u64());
917 assert!(v.is_u128());
918 assert_eq!(v.value_type(), ValueType::U128);
919 }
920 let v = Value::from("no u64");
921 assert!(!v.is_u64());
922 #[cfg(feature = "128bit")]
923 assert!(!v.is_u128());
924 }
925
926 #[test]
927 fn conversions_null() {
928 let v = Value::from(());
929 assert!(v.is_null());
930 assert_eq!(v.value_type(), ValueType::Null);
931 let v = Value::from("no null");
932 assert!(!v.is_null());
933 }
934
935 #[test]
936 fn conversions_object() {
937 let v = Value::from(Object::with_capacity_and_hasher(1, ObjectHasher::default()));
938 assert!(v.is_object());
939 assert_eq!(v.value_type(), ValueType::Object);
940 let v = Value::from("no object");
941 assert!(!v.is_object());
942 }
943
944 #[test]
945 fn conversions_str() {
946 let v = Value::from("bla");
947 assert!(v.is_str());
948 assert_eq!(v.value_type(), ValueType::String);
949 let v = Value::from(42);
950 assert!(!v.is_str());
951 }
952
953 #[test]
954 fn default() {
955 assert_eq!(Value::default(), Value::null());
956 }
957
958 #[cfg(not(target_arch = "wasm32"))]
959 use proptest::prelude::*;
960
961 #[cfg(not(target_arch = "wasm32"))]
962 fn arb_value() -> BoxedStrategy<Value<'static>> {
963 let leaf = prop_oneof![
964 Just(Value::Static(StaticNode::Null)),
965 any::<bool>()
966 .prop_map(StaticNode::Bool)
967 .prop_map(Value::Static),
968 any::<i64>()
969 .prop_map(StaticNode::I64)
970 .prop_map(Value::Static),
971 any::<u64>()
972 .prop_map(StaticNode::U64)
973 .prop_map(Value::Static),
974 any::<f64>()
975 .prop_map(StaticNode::from)
976 .prop_map(Value::Static),
977 ".*".prop_map(Value::from),
978 ];
979 leaf.prop_recursive(
980 8, 256, 10, |inner| {
984 prop_oneof![
985 prop::collection::vec(inner.clone(), 0..10).prop_map(Value::from),
987 prop::collection::hash_map(".*".prop_map(Cow::from), inner, 0..10)
988 .prop_map(|m| m.into_iter().collect()),
989 ]
990 },
991 )
992 .boxed()
993 }
994
995 #[cfg(not(target_arch = "wasm32"))]
996 proptest! {
997 #![proptest_config(ProptestConfig {
998 .. ProptestConfig::default()
999 })]
1000
1001 #[test]
1002 fn prop_to_owned(borrowed in arb_value()) {
1003 use crate::OwnedValue;
1004 let owned: OwnedValue = borrowed.clone().into();
1005 prop_assert_eq!(borrowed, owned);
1006 }
1007 #[test]
1008 fn prop_into_static(borrowed in arb_value()) {
1009 let static_borrowed = borrowed.clone().into_static();
1010 assert_eq!(borrowed, static_borrowed);
1011 }
1012 #[test]
1013 fn prop_clone_static(borrowed in arb_value()) {
1014 let static_borrowed = borrowed.clone_static();
1015 assert_eq!(borrowed, static_borrowed);
1016 }
1017 #[test]
1018 fn prop_serialize_deserialize(borrowed in arb_value()) {
1019 let mut string = borrowed.encode();
1020 let bytes = unsafe{ string.as_bytes_mut()};
1021 let decoded = to_value(bytes).expect("Failed to decode");
1022 prop_assert_eq!(borrowed, decoded);
1023 }
1024 #[test]
1025 #[allow(clippy::float_cmp)]
1026 fn prop_f64_cmp(f in proptest::num::f64::NORMAL) {
1027 let v: Value = f.into();
1028 prop_assert_eq!(v, f);
1029
1030 }
1031
1032 #[test]
1033 #[allow(clippy::float_cmp)]
1034 fn prop_f32_cmp(f in proptest::num::f32::NORMAL) {
1035 let v: Value = f.into();
1036 prop_assert_eq!(v, f);
1037
1038 }
1039 #[test]
1040 fn prop_i64_cmp(f in proptest::num::i64::ANY) {
1041 let v: Value = f.into();
1042 prop_assert_eq!(v, f);
1043 }
1044 #[test]
1045 fn prop_i32_cmp(f in proptest::num::i32::ANY) {
1046 let v: Value = f.into();
1047 prop_assert_eq!(v, f);
1048 }
1049 #[test]
1050 fn prop_i16_cmp(f in proptest::num::i16::ANY) {
1051 let v: Value = f.into();
1052 prop_assert_eq!(v, f);
1053 }
1054 #[test]
1055 fn prop_i8_cmp(f in proptest::num::i8::ANY) {
1056 let v: Value = f.into();
1057 prop_assert_eq!(v, f);
1058 }
1059 #[test]
1060 fn prop_u64_cmp(f in proptest::num::u64::ANY) {
1061 let v: Value = f.into();
1062 prop_assert_eq!(v, f);
1063 }
1064
1065 #[test]
1066 fn prop_usize_cmp(f in proptest::num::usize::ANY) {
1067 let v: Value = f.into();
1068 prop_assert_eq!(v, f);
1069 }
1070 #[test]
1071 fn prop_u32_cmp(f in proptest::num::u32::ANY) {
1072 let v: Value = f.into();
1073 prop_assert_eq!(v, f);
1074 }
1075 #[test]
1076 fn prop_u16_cmp(f in proptest::num::u16::ANY) {
1077 let v: Value = f.into();
1078 prop_assert_eq!(v, f);
1079 }
1080 #[test]
1081 fn prop_u8_cmp(f in proptest::num::u8::ANY) {
1082 let v: Value = f.into();
1083 assert_eq!(v, &f);
1084 prop_assert_eq!(v, f);
1085 }
1086 #[test]
1087 fn prop_string_cmp(f in ".*") {
1088 let v: Value = f.clone().into();
1089 prop_assert_eq!(v.clone(), f.as_str());
1090 prop_assert_eq!(v, f);
1091 }
1092
1093 }
1094 #[test]
1095 fn test_union_cmp() {
1096 let v: Value = ().into();
1097 assert_eq!(v, ());
1098 }
1099 #[test]
1100 #[allow(clippy::bool_assert_comparison)]
1101 fn test_bool_cmp() {
1102 let v: Value = true.into();
1103 assert_eq!(v, true);
1104 let v: Value = false.into();
1105 assert_eq!(v, false);
1106 }
1107 #[test]
1108 fn test_slice_cmp() {
1109 use std::iter::FromIterator;
1110 let v: Value = Value::from_iter(vec!["a", "b"]);
1111 assert_eq!(v, &["a", "b"][..]);
1112 }
1113 #[test]
1114 fn test_hashmap_cmp() {
1115 use std::iter::FromIterator;
1116 let v: Value = Value::from_iter(vec![("a", 1)]);
1117 assert_eq!(
1118 v,
1119 [("a", 1)]
1120 .iter()
1121 .copied()
1122 .collect::<std::collections::HashMap<&str, i32>>()
1123 );
1124 }
1125
1126 #[test]
1127 fn test_option_from() {
1128 let v: Option<u8> = None;
1129 let v: Value = v.into();
1130 assert_eq!(v, ());
1131 let v: Option<u8> = Some(42);
1132 let v: Value = v.into();
1133 assert_eq!(v, 42);
1134 }
1135
1136 }