1mod cmp;
24mod from;
25mod serialize;
26
27use super::ObjectHasher;
28use crate::{Buffers, prelude::*};
29use crate::{Deserializer, Node, Result};
30use crate::{cow::Cow, safer_unchecked::GetSaferUnchecked as _};
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 fn null() -> Self {
165 Self::Static(StaticNode::Null)
166 }
167 #[cfg_attr(not(feature = "no-inline"), inline)]
168 fn array_with_capacity(capacity: usize) -> Self {
169 Self::Array(Box::new(Vec::with_capacity(capacity)))
170 }
171 #[cfg_attr(not(feature = "no-inline"), inline)]
172 fn object_with_capacity(capacity: usize) -> Self {
173 Self::Object(Box::new(Object::with_capacity_and_hasher(
174 capacity,
175 ObjectHasher::default(),
176 )))
177 }
178}
179
180impl<'value> ValueAsMutArray for Value<'value> {
181 type Array = Array<'value>;
182 #[cfg_attr(not(feature = "no-inline"), inline)]
183 fn as_array_mut(&mut self) -> Option<&mut Vec<Value<'value>>> {
184 match self {
185 Self::Array(a) => Some(a),
186 _ => None,
187 }
188 }
189}
190impl<'value> ValueAsMutObject for Value<'value> {
191 type Object = Object<'value>;
192 #[cfg_attr(not(feature = "no-inline"), inline)]
211 fn as_object_mut(&mut self) -> Option<&mut Object<'value>> {
212 match self {
213 Self::Object(m) => Some(m),
214 _ => None,
215 }
216 }
217}
218
219impl TypedValue for Value<'_> {
220 #[cfg_attr(not(feature = "no-inline"), inline)]
221 fn value_type(&self) -> ValueType {
222 match self {
223 Self::Static(s) => s.value_type(),
224 Self::String(_) => ValueType::String,
225 Self::Array(_) => ValueType::Array,
226 Self::Object(_) => ValueType::Object,
227 }
228 }
229}
230impl ValueAsScalar for Value<'_> {
231 #[cfg_attr(not(feature = "no-inline"), inline)]
232 fn as_null(&self) -> Option<()> {
233 self.as_static()?.as_null()
234 }
235
236 #[cfg_attr(not(feature = "no-inline"), inline)]
237 fn as_bool(&self) -> Option<bool> {
238 self.as_static()?.as_bool()
239 }
240
241 #[cfg_attr(not(feature = "no-inline"), inline)]
242 fn as_i64(&self) -> Option<i64> {
243 self.as_static()?.as_i64()
244 }
245
246 #[cfg_attr(not(feature = "no-inline"), inline)]
247 fn as_i128(&self) -> Option<i128> {
248 self.as_static()?.as_i128()
249 }
250
251 #[cfg_attr(not(feature = "no-inline"), inline)]
252 fn as_u64(&self) -> Option<u64> {
253 self.as_static()?.as_u64()
254 }
255
256 #[cfg_attr(not(feature = "no-inline"), inline)]
257 fn as_u128(&self) -> Option<u128> {
258 self.as_static()?.as_u128()
259 }
260
261 #[cfg_attr(not(feature = "no-inline"), inline)]
262 fn as_f64(&self) -> Option<f64> {
263 self.as_static()?.as_f64()
264 }
265
266 #[cfg_attr(not(feature = "no-inline"), inline)]
267 fn cast_f64(&self) -> Option<f64> {
268 self.as_static()?.cast_f64()
269 }
270
271 #[cfg_attr(not(feature = "no-inline"), inline)]
272 fn as_str(&self) -> Option<&str> {
273 use std::borrow::Borrow;
274 match self {
275 Self::String(s) => Some(s.borrow()),
276 _ => None,
277 }
278 }
279}
280impl<'value> ValueAsArray for Value<'value> {
281 type Array = Array<'value>;
282
283 #[cfg_attr(not(feature = "no-inline"), inline)]
284 fn as_array(&self) -> Option<&Vec<Value<'value>>> {
285 match self {
286 Self::Array(a) => Some(a),
287 _ => None,
288 }
289 }
290}
291
292impl<'value> ValueAsObject for Value<'value> {
293 type Object = Object<'value>;
294
295 #[cfg_attr(not(feature = "no-inline"), inline)]
296 fn as_object(&self) -> Option<&Object<'value>> {
297 match self {
298 Self::Object(m) => Some(m),
299 _ => None,
300 }
301 }
302}
303
304impl<'value> ValueIntoString for Value<'value> {
305 type String = Cow<'value, str>;
306
307 fn into_string(self) -> Option<<Self as ValueIntoString>::String> {
308 match self {
309 Self::String(s) => Some(s),
310 _ => None,
311 }
312 }
313}
314
315impl<'value> ValueIntoArray for Value<'value> {
316 type Array = Array<'value>;
317
318 fn into_array(self) -> Option<<Self as ValueIntoArray>::Array> {
319 match self {
320 Self::Array(a) => Some(*a),
321 _ => None,
322 }
323 }
324}
325
326impl<'value> ValueIntoObject for Value<'value> {
327 type Object = Object<'value>;
328
329 fn into_object(self) -> Option<<Self as ValueIntoObject>::Object> {
330 match self {
331 Self::Object(a) => Some(*a),
332 _ => None,
333 }
334 }
335}
336
337#[cfg(not(tarpaulin_include))]
338impl fmt::Display for Value<'_> {
339 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
340 match self {
341 Self::Static(s) => write!(f, "{s}"),
342 Self::String(s) => write!(f, "{s}"),
343 Self::Array(a) => write!(f, "{a:?}"),
344 Self::Object(o) => write!(f, "{o:?}"),
345 }
346 }
347}
348
349impl<'value> Index<&str> for Value<'value> {
350 type Output = Value<'value>;
351 #[cfg_attr(not(feature = "no-inline"), inline)]
352 fn index(&self, index: &str) -> &Self::Output {
353 self.get(index).expect("index out of bounds")
354 }
355}
356
357impl<'value> Index<usize> for Value<'value> {
358 type Output = Value<'value>;
359 #[cfg_attr(not(feature = "no-inline"), inline)]
360 fn index(&self, index: usize) -> &Self::Output {
361 self.get_idx(index).expect("index out of bounds")
362 }
363}
364
365impl IndexMut<&str> for Value<'_> {
366 #[cfg_attr(not(feature = "no-inline"), inline)]
367 fn index_mut(&mut self, index: &str) -> &mut Self::Output {
368 self.get_mut(index).expect("index out of bounds")
369 }
370}
371
372impl IndexMut<usize> for Value<'_> {
373 #[cfg_attr(not(feature = "no-inline"), inline)]
374 fn index_mut(&mut self, index: usize) -> &mut Self::Output {
375 self.get_idx_mut(index).expect("index out of bounds")
376 }
377}
378
379impl Default for Value<'_> {
380 #[cfg_attr(not(feature = "no-inline"), inline)]
381 fn default() -> Self {
382 Self::Static(StaticNode::Null)
383 }
384}
385
386pub(super) struct BorrowDeserializer<'de>(Deserializer<'de>);
387
388impl<'de> BorrowDeserializer<'de> {
389 pub fn from_deserializer(de: Deserializer<'de>) -> Self {
390 Self(de)
391 }
392
393 #[cfg_attr(not(feature = "no-inline"), inline)]
394 pub fn parse(&mut self) -> Value<'de> {
395 match unsafe { self.0.next_() } {
396 Node::Static(s) => Value::Static(s),
397 Node::String(s) => Value::from(s),
398 Node::Array { len, count: _ } => self.parse_array(len),
399 Node::Object { len, count: _ } => self.parse_map(len),
400 }
401 }
402
403 #[cfg_attr(not(feature = "no-inline"), inline)]
404 fn parse_array(&mut self, len: usize) -> Value<'de> {
405 let mut res: Vec<Value<'de>> = Vec::with_capacity(len);
409 let res_ptr = res.as_mut_ptr();
410 unsafe {
411 for i in 0..len {
412 res_ptr.add(i).write(self.parse());
413 }
414 res.set_len(len);
415 }
416 Value::Array(Box::new(res))
417 }
418
419 #[cfg_attr(not(feature = "no-inline"), inline)]
420 fn parse_map(&mut self, len: usize) -> Value<'de> {
421 let mut res = Object::with_capacity_and_hasher(len, ObjectHasher::default());
422
423 for _ in 0..len {
426 if let Node::String(key) = unsafe { self.0.next_() } {
427 #[cfg(not(feature = "value-no-dup-keys"))]
428 unsafe {
429 res.insert_nocheck(key.into(), self.parse());
430 };
431 #[cfg(feature = "value-no-dup-keys")]
432 res.insert(key.into(), self.parse());
433 } else {
434 unreachable!("parse_map: key not a string");
435 }
436 }
437 Value::from(res)
438 }
439}
440pub(super) struct BorrowSliceDeserializer<'tape, 'de> {
441 tape: &'tape [Node<'de>],
442 idx: usize,
443}
444impl<'tape, 'de> BorrowSliceDeserializer<'tape, 'de> {
445 pub fn from_tape(de: &'tape [Node<'de>]) -> Self {
446 Self { tape: de, idx: 0 }
447 }
448 #[cfg_attr(not(feature = "no-inline"), inline)]
449 pub unsafe fn next_(&mut self) -> Node<'de> {
450 let r = unsafe { *self.tape.get_kinda_unchecked(self.idx) };
451 self.idx += 1;
452 r
453 }
454
455 #[cfg_attr(not(feature = "no-inline"), inline)]
456 pub fn parse(&mut self) -> Value<'de> {
457 match unsafe { self.next_() } {
458 Node::Static(s) => Value::Static(s),
459 Node::String(s) => Value::from(s),
460 Node::Array { len, count: _ } => self.parse_array(len),
461 Node::Object { len, count: _ } => self.parse_map(len),
462 }
463 }
464
465 #[cfg_attr(not(feature = "no-inline"), inline)]
466 fn parse_array(&mut self, len: usize) -> Value<'de> {
467 let mut res: Vec<Value<'de>> = Vec::with_capacity(len);
471 let res_ptr = res.as_mut_ptr();
472 unsafe {
473 for i in 0..len {
474 res_ptr.add(i).write(self.parse());
475 }
476 res.set_len(len);
477 }
478 Value::Array(Box::new(res))
479 }
480
481 #[cfg_attr(not(feature = "no-inline"), inline)]
482 fn parse_map(&mut self, len: usize) -> Value<'de> {
483 let mut res = Object::with_capacity_and_hasher(len, ObjectHasher::default());
484
485 for _ in 0..len {
488 if let Node::String(key) = unsafe { self.next_() } {
489 #[cfg(not(feature = "value-no-dup-keys"))]
490 unsafe {
491 res.insert_nocheck(key.into(), self.parse());
492 };
493 #[cfg(feature = "value-no-dup-keys")]
494 res.insert(key.into(), self.parse());
495 } else {
496 unreachable!("parse_map: key needs to be a string");
497 }
498 }
499 Value::from(res)
500 }
501}
502
503#[cfg(test)]
504mod test {
505 #![allow(clippy::ignored_unit_patterns)]
506 #![allow(clippy::cognitive_complexity)]
507 use super::*;
508
509 #[test]
510 fn object_access() {
511 let mut v = Value::null();
512 assert_eq!(v.insert("key", ()), Err(AccessError::NotAnObject));
513 assert_eq!(v.remove("key"), Err(AccessError::NotAnObject));
514 let mut v = Value::object();
515 assert_eq!(v.insert("key", 1), Ok(None));
516 assert_eq!(v["key"], 1);
517 assert_eq!(v.insert("key", 2), Ok(Some(Value::from(1))));
518 v["key"] = 3.into();
519 assert_eq!(v.remove("key"), Ok(Some(Value::from(3))));
520 }
521
522 #[test]
523 fn array_access() {
524 let mut v = Value::null();
525 assert_eq!(v.push("key"), Err(AccessError::NotAnArray));
526 assert_eq!(v.pop(), Err(AccessError::NotAnArray));
527 let mut v = Value::array();
528 assert_eq!(v.push(1), Ok(()));
529 assert_eq!(v.push(2), Ok(()));
530 assert_eq!(v[0], 1);
531 v[0] = 0.into();
532 v[1] = 1.into();
533 assert_eq!(v.pop(), Ok(Some(Value::from(1))));
534 assert_eq!(v.pop(), Ok(Some(Value::from(0))));
535 assert_eq!(v.pop(), Ok(None));
536 }
537
538 #[cfg(feature = "128bit")]
539 #[test]
540 fn conversions_i128() {
541 let v = Value::from(i128::MAX);
542 assert!(v.is_i128());
543 assert!(v.is_u128());
544 assert!(!v.is_i64());
545 assert!(!v.is_u64());
546 assert!(!v.is_i32());
547 assert!(!v.is_u32());
548 assert!(!v.is_i16());
549 assert!(!v.is_u16());
550 assert!(!v.is_i8());
551 assert!(!v.is_u8());
552 assert!(!v.is_f64());
553 assert!(!v.is_f32());
554 assert!(v.is_f64_castable());
555 let v = Value::from(i128::MIN);
556 assert!(v.is_i128());
557 assert!(!v.is_u128());
558 assert!(!v.is_i64());
559 assert!(!v.is_u64());
560 assert!(!v.is_i32());
561 assert!(!v.is_u32());
562 assert!(!v.is_i16());
563 assert!(!v.is_u16());
564 assert!(!v.is_i8());
565 assert!(!v.is_u8());
566 assert!(!v.is_f64());
567 assert!(!v.is_f32());
568 assert!(v.is_f64_castable());
569 }
570
571 #[test]
572 fn conversions_i64() {
573 let v = Value::from(i64::MAX);
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 let v = Value::from(i64::MIN);
588 assert!(v.is_i128());
589 assert!(!v.is_u128());
590 assert!(v.is_i64());
591 assert!(!v.is_u64());
592 assert!(!v.is_i32());
593 assert!(!v.is_u32());
594 assert!(!v.is_i16());
595 assert!(!v.is_u16());
596 assert!(!v.is_i8());
597 assert!(!v.is_u8());
598 assert!(!v.is_f64());
599 assert!(!v.is_f32());
600 assert!(v.is_f64_castable());
601 }
602
603 #[test]
604 fn conversions_i32() {
605 let v = Value::from(i32::MAX);
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 let v = Value::from(i32::MIN);
620 assert!(v.is_i128());
621 assert!(!v.is_u128());
622 assert!(v.is_i64());
623 assert!(!v.is_u64());
624 assert!(v.is_i32());
625 assert!(!v.is_u32());
626 assert!(!v.is_i16());
627 assert!(!v.is_u16());
628 assert!(!v.is_i8());
629 assert!(!v.is_u8());
630 assert!(!v.is_f64());
631 assert!(!v.is_f32());
632 assert!(v.is_f64_castable());
633 }
634
635 #[test]
636 fn conversions_i16() {
637 let v = Value::from(i16::MAX);
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 let v = Value::from(i16::MIN);
652 assert!(v.is_i128());
653 assert!(!v.is_u128());
654 assert!(v.is_i64());
655 assert!(!v.is_u64());
656 assert!(v.is_i32());
657 assert!(!v.is_u32());
658 assert!(v.is_i16());
659 assert!(!v.is_u16());
660 assert!(!v.is_i8());
661 assert!(!v.is_u8());
662 assert!(!v.is_f64());
663 assert!(!v.is_f32());
664 assert!(v.is_f64_castable());
665 assert!(v.is_f64_castable());
666 }
667
668 #[test]
669 fn conversions_i8() {
670 let v = Value::from(i8::MAX);
671 assert!(v.is_i128());
672 assert!(v.is_u128());
673 assert!(v.is_i64());
674 assert!(v.is_u64());
675 assert!(v.is_i32());
676 assert!(v.is_u32());
677 assert!(v.is_i16());
678 assert!(v.is_u16());
679 assert!(v.is_i8());
680 assert!(v.is_u8());
681 assert!(!v.is_f64());
682 assert!(!v.is_f32());
683 assert!(v.is_f64_castable());
684 let v = Value::from(i8::MIN);
685 assert!(v.is_i128());
686 assert!(!v.is_u128());
687 assert!(v.is_i64());
688 assert!(!v.is_u64());
689 assert!(v.is_i32());
690 assert!(!v.is_u32());
691 assert!(v.is_i16());
692 assert!(!v.is_u16());
693 assert!(v.is_i8());
694 assert!(!v.is_u8());
695 assert!(!v.is_f64());
696 assert!(!v.is_f32());
697 assert!(v.is_f64_castable());
698 }
699
700 #[test]
701 fn conversions_usize() {
702 let v = Value::from(usize::MIN as u64);
703 assert!(v.is_i128());
704 assert!(v.is_u128());
705 assert!(v.is_i64());
706 assert!(v.is_u64());
707 assert!(v.is_usize());
708 assert!(v.is_i32());
709 assert!(v.is_u32());
710 assert!(v.is_i16());
711 assert!(v.is_u16());
712 assert!(v.is_i8());
713 assert!(v.is_u8());
714 assert!(!v.is_f64());
715 assert!(!v.is_f32());
716 assert!(!v.is_f64());
717 assert!(!v.is_f32());
718 assert!(v.is_f64_castable());
719 }
720
721 #[cfg(feature = "128bit")]
722 #[test]
723 fn conversions_u128() {
724 let v = Value::from(u128::MIN);
725 assert!(v.is_i128());
726 assert!(v.is_u128());
727 assert!(v.is_i64());
728 assert!(v.is_u64());
729 assert!(v.is_i32());
730 assert!(v.is_u32());
731 assert!(v.is_i16());
732 assert!(v.is_u16());
733 assert!(v.is_i8());
734 assert!(v.is_u8());
735 assert!(!v.is_f64());
736 assert!(!v.is_f32());
737 assert!(v.is_f64_castable());
738 }
739
740 #[test]
741 fn conversions_u64() {
742 let v = Value::from(u64::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_u32() {
760 let v = Value::from(u32::MAX);
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_u16() {
778 let v = Value::from(u16::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_u8() {
796 let v = Value::from(u8::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_f64() {
814 let v = Value::from(f64::MAX);
815 assert!(!v.is_i64());
816 assert!(!v.is_u64());
817 assert!(v.is_f64());
818 assert!(!v.is_f32());
819 assert!(v.is_f64_castable());
820 let v = Value::from(f64::MIN);
821 assert!(!v.is_i64());
822 assert!(!v.is_u64());
823 assert!(v.is_f64());
824 assert!(!v.is_f32());
825 assert!(v.is_f64_castable());
826 let v = Value::from("not a f64");
827 assert!(!v.is_f64_castable());
828 }
829
830 #[test]
831 fn conversions_f32() {
832 let v = Value::from(f32::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(f32::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 }
845
846 #[test]
847 fn conversions_array() {
848 let v = Value::from(vec![true]);
849 assert!(v.is_array());
850 assert_eq!(v.value_type(), ValueType::Array);
851 let v = Value::from("no array");
852 assert!(!v.is_array());
853 }
854
855 #[test]
856 fn conversions_bool() {
857 let v = Value::from(true);
858 assert!(v.is_bool());
859 assert_eq!(v.value_type(), ValueType::Bool);
860 let v = Value::from("no bool");
861 assert!(!v.is_bool());
862 }
863
864 #[test]
865 fn conversions_float() {
866 let v = Value::from(42.0);
867 assert!(v.is_f64());
868 assert_eq!(v.value_type(), ValueType::F64);
869 let v = Value::from("no float");
870 assert!(!v.is_f64());
871 }
872
873 #[test]
874 fn conversions_int() {
875 let v = Value::from(-42);
876 assert!(v.is_i64());
877 assert_eq!(v.value_type(), ValueType::I64);
878 #[cfg(feature = "128bit")]
879 {
880 let v = Value::from(-42_i128);
881 assert!(v.is_i64());
882 assert!(v.is_i128());
883 assert_eq!(v.value_type(), ValueType::I128);
884 }
885 let v = Value::from("no i64");
886 assert!(!v.is_i64());
887 assert!(!v.is_i128());
888 }
889
890 #[test]
891 fn conversions_uint() {
892 let v = Value::from(42_u64);
893 assert!(v.is_u64());
894 assert_eq!(v.value_type(), ValueType::U64);
895 #[cfg(feature = "128bit")]
896 {
897 let v = Value::from(42_u128);
898 assert!(v.is_u64());
899 assert!(v.is_u128());
900 assert_eq!(v.value_type(), ValueType::U128);
901 }
902 let v = Value::from("no u64");
903 assert!(!v.is_u64());
904 #[cfg(feature = "128bit")]
905 assert!(!v.is_u128());
906 }
907
908 #[test]
909 fn conversions_null() {
910 let v = Value::from(());
911 assert!(v.is_null());
912 assert_eq!(v.value_type(), ValueType::Null);
913 let v = Value::from("no null");
914 assert!(!v.is_null());
915 }
916
917 #[test]
918 fn conversions_object() {
919 let v = Value::from(Object::with_capacity_and_hasher(1, ObjectHasher::default()));
920 assert!(v.is_object());
921 assert_eq!(v.value_type(), ValueType::Object);
922 let v = Value::from("no object");
923 assert!(!v.is_object());
924 }
925
926 #[test]
927 fn conversions_str() {
928 let v = Value::from("bla");
929 assert!(v.is_str());
930 assert_eq!(v.value_type(), ValueType::String);
931 let v = Value::from(42);
932 assert!(!v.is_str());
933 }
934
935 #[test]
936 fn default() {
937 assert_eq!(Value::default(), Value::null());
938 }
939
940 #[cfg(not(target_arch = "wasm32"))]
941 use proptest::prelude::*;
942
943 #[cfg(not(target_arch = "wasm32"))]
944 fn arb_value() -> BoxedStrategy<Value<'static>> {
945 let leaf = prop_oneof![
946 Just(Value::Static(StaticNode::Null)),
947 any::<bool>()
948 .prop_map(StaticNode::Bool)
949 .prop_map(Value::Static),
950 any::<i64>()
951 .prop_map(StaticNode::I64)
952 .prop_map(Value::Static),
953 any::<u64>()
954 .prop_map(StaticNode::U64)
955 .prop_map(Value::Static),
956 any::<f64>()
957 .prop_map(StaticNode::from)
958 .prop_map(Value::Static),
959 ".*".prop_map(Value::from),
960 ];
961 leaf.prop_recursive(
962 8, 256, 10, |inner| {
966 prop_oneof![
967 prop::collection::vec(inner.clone(), 0..10).prop_map(Value::from),
969 prop::collection::hash_map(".*".prop_map(Cow::from), inner, 0..10)
970 .prop_map(|m| m.into_iter().collect()),
971 ]
972 },
973 )
974 .boxed()
975 }
976
977 #[cfg(not(target_arch = "wasm32"))]
978 proptest! {
979 #![proptest_config(ProptestConfig {
980 .. ProptestConfig::default()
981 })]
982
983 #[test]
984 fn prop_to_owned(borrowed in arb_value()) {
985 use crate::OwnedValue;
986 let owned: OwnedValue = borrowed.clone().into();
987 prop_assert_eq!(borrowed, owned);
988 }
989 #[test]
990 fn prop_into_static(borrowed in arb_value()) {
991 let static_borrowed = borrowed.clone().into_static();
992 assert_eq!(borrowed, static_borrowed);
993 }
994 #[test]
995 fn prop_clone_static(borrowed in arb_value()) {
996 let static_borrowed = borrowed.clone_static();
997 assert_eq!(borrowed, static_borrowed);
998 }
999 #[test]
1000 fn prop_serialize_deserialize(borrowed in arb_value()) {
1001 let mut string = borrowed.encode();
1002 let bytes = unsafe{ string.as_bytes_mut()};
1003 let decoded = to_value(bytes).expect("Failed to decode");
1004 prop_assert_eq!(borrowed, decoded);
1005 }
1006 #[test]
1007 #[allow(clippy::float_cmp)]
1008 fn prop_f64_cmp(f in proptest::num::f64::NORMAL) {
1009 let v: Value = f.into();
1010 prop_assert_eq!(v, f);
1011
1012 }
1013
1014 #[test]
1015 #[allow(clippy::float_cmp)]
1016 fn prop_f32_cmp(f in proptest::num::f32::NORMAL) {
1017 let v: Value = f.into();
1018 prop_assert_eq!(v, f);
1019
1020 }
1021 #[test]
1022 fn prop_i64_cmp(f in proptest::num::i64::ANY) {
1023 let v: Value = f.into();
1024 prop_assert_eq!(v, f);
1025 }
1026 #[test]
1027 fn prop_i32_cmp(f in proptest::num::i32::ANY) {
1028 let v: Value = f.into();
1029 prop_assert_eq!(v, f);
1030 }
1031 #[test]
1032 fn prop_i16_cmp(f in proptest::num::i16::ANY) {
1033 let v: Value = f.into();
1034 prop_assert_eq!(v, f);
1035 }
1036 #[test]
1037 fn prop_i8_cmp(f in proptest::num::i8::ANY) {
1038 let v: Value = f.into();
1039 prop_assert_eq!(v, f);
1040 }
1041 #[test]
1042 fn prop_u64_cmp(f in proptest::num::u64::ANY) {
1043 let v: Value = f.into();
1044 prop_assert_eq!(v, f);
1045 }
1046
1047 #[test]
1048 fn prop_usize_cmp(f in proptest::num::usize::ANY) {
1049 let v: Value = f.into();
1050 prop_assert_eq!(v, f);
1051 }
1052 #[test]
1053 fn prop_u32_cmp(f in proptest::num::u32::ANY) {
1054 let v: Value = f.into();
1055 prop_assert_eq!(v, f);
1056 }
1057 #[test]
1058 fn prop_u16_cmp(f in proptest::num::u16::ANY) {
1059 let v: Value = f.into();
1060 prop_assert_eq!(v, f);
1061 }
1062 #[test]
1063 fn prop_u8_cmp(f in proptest::num::u8::ANY) {
1064 let v: Value = f.into();
1065 assert_eq!(v, &f);
1066 prop_assert_eq!(v, f);
1067 }
1068 #[test]
1069 fn prop_string_cmp(f in ".*") {
1070 let v: Value = f.clone().into();
1071 prop_assert_eq!(v.clone(), f.as_str());
1072 prop_assert_eq!(v, f);
1073 }
1074
1075 }
1076 #[test]
1077 fn test_union_cmp() {
1078 let v: Value = ().into();
1079 assert_eq!(v, ());
1080 }
1081 #[test]
1082 #[allow(clippy::bool_assert_comparison)]
1083 fn test_bool_cmp() {
1084 let v: Value = true.into();
1085 assert_eq!(v, true);
1086 let v: Value = false.into();
1087 assert_eq!(v, false);
1088 }
1089 #[test]
1090 fn test_slice_cmp() {
1091 use std::iter::FromIterator;
1092 let v: Value = Value::from_iter(vec!["a", "b"]);
1093 assert_eq!(v, &["a", "b"][..]);
1094 }
1095 #[test]
1096 fn test_hashmap_cmp() {
1097 use std::iter::FromIterator;
1098 let v: Value = Value::from_iter(vec![("a", 1)]);
1099 assert_eq!(
1100 v,
1101 [("a", 1)]
1102 .iter()
1103 .copied()
1104 .collect::<std::collections::HashMap<&str, i32>>()
1105 );
1106 }
1107
1108 #[test]
1109 fn test_option_from() {
1110 let v: Option<u8> = None;
1111 let v: Value = v.into();
1112 assert_eq!(v, ());
1113 let v: Option<u8> = Some(42);
1114 let v: Value = v.into();
1115 assert_eq!(v, 42);
1116 }
1117
1118 }