Skip to main content

sonic_rs/value/
node.rs

1use core::mem::size_of;
2#[cfg(feature = "sort_keys")]
3use std::collections::BTreeMap;
4use std::{
5    alloc::Layout,
6    fmt::{Debug, Display, Formatter},
7    mem::{transmute, ManuallyDrop},
8    ptr::NonNull,
9    slice::from_raw_parts,
10    str::from_utf8_unchecked,
11    sync::Arc,
12};
13
14#[cfg(not(feature = "sort_keys"))]
15use ahash::AHashMap;
16use faststr::FastStr;
17use ref_cast::RefCast;
18use serde::ser::{Serialize, SerializeMap, SerializeSeq};
19
20use super::{
21    object::Pair,
22    shared::Shared,
23    tls_buffer::TlsBuf,
24    value_trait::{JsonContainerTrait, JsonValueMutTrait},
25    visitor::JsonVisitor,
26};
27use crate::{
28    config::DeserializeCfg,
29    error::Result,
30    index::Index,
31    parser::Parser,
32    reader::{PaddedSliceRead, Reader},
33    serde::tri,
34    util::string::str_from_raw_parts,
35    value::{array::Array, object::Object, value_trait::JsonValueTrait},
36    JsonNumberTrait, JsonType, Number, RawNumber,
37};
38
39/// Represents any valid JSON value.
40///
41/// `Value` can be parsed from a JSON and from any type that implements `serde::Serialize`.
42///
43/// # Example
44/// ```
45/// use sonic_rs::json;
46/// use sonic_rs::value::Value;
47///
48/// let v1 = json!({"a": 123});
49/// let v2: Value = sonic_rs::from_str(r#"{"a": 123}"#).unwrap();
50/// let v3 = {
51///     use std::collections::HashMap;
52///     let mut map: HashMap<&str, i32> = HashMap::new();
53///     map.insert(&"a", 123);
54///     sonic_rs::to_value(&map).unwrap()
55/// };
56///
57/// assert_eq!(v1, v2);
58/// assert_eq!(v2, v3);
59///
60/// assert_eq!(v1["a"], 123);
61/// ```
62///
63/// # Notes
64///
65/// Not use any unsafe invalid_reference_casting for `Value`, it will cause UB.
66///
67/// ```rust,no_run
68/// use sonic_rs::{from_str, Value};
69/// let json = r#"["a", "b", "c"]"#;
70/// let root: Value = from_str(json).unwrap();
71/// let immref = &root["b"];
72///
73/// // This is dangerous, will coredump when using sanitizer
74/// #[allow(invalid_reference_casting)]
75/// let ub_cast = unsafe { &mut *(immref as *const _ as *mut Value) };
76/// let _ub = std::mem::take(ub_cast);
77/// ```
78#[repr(C)]
79pub struct Value {
80    pub(crate) meta: Meta,
81    pub(crate) data: Data,
82}
83
84#[rustfmt::skip]
85// A compact and mutable JSON Value.
86//
87//  Thera are three kind nodes into the Value:
88//  - Static Node: no need drop
89//  - Owned Node : mutable
90//  - Shared Node: in SharedDom, not mutable
91//
92// |  Kind        | 3 bits | 5 bits |       24 bits     |     ---->  32 bits ---->       |    32 bits    |    32 bits    |       limit          |
93// |--------------|-----------------|-------------------|--------------------------------|-------------------------------|----------------------|
94// |   Null       |   0    |   0    |                                                    +                               |                      |
95// |   True       |   0    |   1    |                                                    +                               |                      |
96// |   False      |   0    |   2    |                                                    +                               |                      |
97// |   I64        |   0    |   3    |                                                    +             i64               |                      |
98// |   U64        |   0    |   4    |                                                    +             u64               |                      |
99// |   F64        |   0    |   5    |                                                    +             f64               |                      |
100// |  empty arr   |   0    |   6    |                                                                                    |
101// |  empty obj   |   0    |   7    |                                                                                    |
102// |  static str  |   0    |   8    |                   |           string length        +          *const u8            | excced will fallback |
103// |   faststr    |   1    |   0    |                                                    +         Box<FastStr>          |                      |
104// |rawnum_faststr|   1    |   1    |                                                    +         Box<FastStr>          |                      |
105// |   arr_mut    |   1    |   2    |                                                    +        Arc<Vec<Node>>         |                      |
106// |   obj_mut    |   1    |   3    |                                                    + Arc<AHashMap<FastStr, Value>> |                      |
107// |   str_node   |   2    |        node idx            |           string length        +          *const u8            |    max len 2^32      |
108// | raw_num_node |   3    |        node idx            |           string length        +          *const u8            |    max len 2^32      |
109// |   arr_node   |   4    |        node idx            |           array length         +          *const Node          |    max len 2^32      |
110// |   obj_node   |   5    |        node idx            |           object length        +          *const Pair          |    max len 2^32      |
111// |   _reserved  |   6    |
112// |  root_node   |   7    |      *const ShardDom (from Arc, MUST aligned 8)             +      *const Node (head)       |                      |
113//
114// NB: we will check the JSON length when parsing, if JSON is >= 4GB, will return a error, so we will not check the limits when parsing or using dom.
115#[allow(clippy::box_collection)]
116#[repr(C)]
117pub(crate) union Data {
118    pub(crate) uval: u64,
119    pub(crate) ival: i64,
120    pub(crate) fval: f64,
121    pub(crate) static_str: NonNull<u8>,
122
123    pub(crate) dom_str: NonNull<u8>,
124    pub(crate) arr_elems: NonNull<Value>,
125    pub(crate) obj_pairs: NonNull<Pair>,
126
127    pub(crate) root: NonNull<Value>,
128
129    pub(crate) str_own: ManuallyDrop<Box<FastStr>>,
130    #[cfg(not(feature = "sort_keys"))]
131    pub(crate) obj_own: ManuallyDrop<Arc<AHashMap<FastStr, Value>>>,
132    #[cfg(feature="sort_keys")]
133    pub(crate) obj_own: ManuallyDrop<Arc<BTreeMap<FastStr, Value>>>,
134    pub(crate) arr_own: ManuallyDrop<Arc<Vec<Value>>>,
135
136    pub(crate) parent: u64,
137}
138
139/// Compact metadata for a `Value` node.
140///
141/// On 64-bit targets this is a union of `u64` and `*const Shared`.
142/// Using a union preserves pointer provenance through storage, enabling
143/// strict-provenance-compatible round-trips for the root_node variant
144/// without needing `expose_provenance` / `with_exposed_provenance`.
145///
146/// On 32-bit targets (e.g. wasm32) the pointer is only 4 bytes while `val`
147/// is 8 bytes, so writing through a `ptr` field would leave the upper half
148/// uninitialized — reading back via `val` would be UB.  Therefore on 32-bit
149/// we fall back to a plain `u64` struct with exposed provenance for the
150/// root_node round-trip.
151///
152/// All non-root variants always read/write through the `val` field.
153/// The root variant writes/reads through the `ptr` field (64-bit) or
154/// through `val` with expose/recover (32-bit).
155#[derive(Copy, Clone)]
156#[cfg(target_pointer_width = "64")]
157#[repr(C)]
158pub(crate) union Meta {
159    val: u64,
160    ptr: *const Shared,
161}
162
163#[derive(Copy, Clone)]
164#[cfg(not(target_pointer_width = "64"))]
165#[repr(transparent)]
166pub(crate) struct Meta {
167    val: u64,
168}
169
170// Safety: Meta contains either a plain integer or a pointer derived from
171// Arc<Shared> (which is Send+Sync). The pointer is never dereferenced
172// through Meta directly — it is only unpacked and used behind Arc's
173// reference counting.
174#[cfg(target_pointer_width = "64")]
175unsafe impl Send for Meta {}
176#[cfg(target_pointer_width = "64")]
177unsafe impl Sync for Meta {}
178
179impl Meta {
180    const STAIC_NODE: u64 = 0;
181    const NULL: u64 = (0 << Self::KIND_BITS);
182    const TRUE: u64 = (1 << Self::KIND_BITS);
183    const FALSE: u64 = (2 << Self::KIND_BITS);
184    const I64: u64 = (3 << Self::KIND_BITS);
185    const U64: u64 = (4 << Self::KIND_BITS);
186    const F64: u64 = (5 << Self::KIND_BITS);
187    const EMPTY_ARR: u64 = (6 << Self::KIND_BITS);
188    const EMPTY_OBJ: u64 = (7 << Self::KIND_BITS);
189    const STATIC_STR: u64 = (8 << Self::KIND_BITS);
190
191    const OWNED_NODE: u64 = 1;
192    const FASTSTR: u64 = 1 | (0 << Self::KIND_BITS);
193    const RAWNUM_FASTSTR: u64 = 1 | (1 << Self::KIND_BITS);
194    const ARR_MUT: u64 = 1 | (2 << Self::KIND_BITS);
195    const OBJ_MUT: u64 = 1 | (3 << Self::KIND_BITS);
196
197    const STR_NODE: u64 = 2;
198    const RAWNUM_NODE: u64 = 3;
199    const ARR_NODE: u64 = 4;
200    const OBJ_NODE: u64 = 5;
201
202    const ROOT_NODE: u64 = 7;
203
204    const KIND_BITS: u64 = 3;
205    const KIND_MASK: u64 = (1 << Self::KIND_BITS) - 1;
206
207    const TYPE_BITS: u64 = 8;
208    const TYPE_MASK: u64 = (1 << Self::TYPE_BITS) - 1;
209
210    const IDX_MASK: u64 = ((1 << Self::LEN_OFFSET) - 1) & !Self::KIND_MASK;
211    const LEN_OFFSET: u64 = 32;
212}
213
214impl Meta {
215    pub const fn new(typ: u64) -> Self {
216        Self { val: typ }
217    }
218
219    fn pack_dom_node(kind: u64, idx: u32, len: u32) -> Self {
220        debug_assert!(matches!(
221            kind,
222            Self::ARR_NODE | Self::OBJ_NODE | Self::STR_NODE | Self::RAWNUM_NODE
223        ));
224        let idx = idx as u64;
225        let len = len as u64;
226        let val = kind | (idx << Self::KIND_BITS) | (len << Self::LEN_OFFSET);
227        Self { val }
228    }
229
230    fn pack_static_str(kind: u64, len: usize) -> Self {
231        assert!(len < (u32::MAX as usize));
232        assert!(kind == Self::STATIC_STR);
233        let val = kind | ((len as u64) << Self::LEN_OFFSET);
234        Self { val }
235    }
236
237    /// Pack a `*const Shared` pointer into a root Meta node.
238    ///
239    /// On 64-bit: stores the tagged pointer through the union `ptr` field,
240    /// preserving provenance (strict-provenance compatible).
241    ///
242    /// On 32-bit: stores through `val` as a u64, using exposed provenance
243    /// for the Arc::increment_strong_count call.  The pointer address fits
244    /// in the low 32 bits of the u64.
245    #[cfg(target_pointer_width = "64")]
246    fn pack_shared(ptr: *const Shared) -> Self {
247        // Arc::increment_strong_count needs provenance covering the full
248        // Arc allocation (header + data). The caller's ptr may come from
249        // &Shared (narrow provenance), so the Arc allocation must be exposed
250        // beforehand (done in parse_with_padding / Deserializer).
251        let addr = ptr.expose_provenance();
252        let wide_ptr = std::ptr::with_exposed_provenance::<Shared>(addr);
253        unsafe { Arc::increment_strong_count(wide_ptr) };
254        // Store tagged pointer through the union ptr field — provenance preserved.
255        let tagged = ptr.map_addr(|a| a | Self::ROOT_NODE as usize);
256        Self { ptr: tagged }
257    }
258
259    #[cfg(not(target_pointer_width = "64"))]
260    fn pack_shared(ptr: *const Shared) -> Self {
261        let addr = ptr.expose_provenance();
262        let wide_ptr = std::ptr::with_exposed_provenance::<Shared>(addr);
263        unsafe { Arc::increment_strong_count(wide_ptr) };
264        let val = addr as u64 | Self::ROOT_NODE;
265        Self { val }
266    }
267
268    /// Read the integer representation of this Meta.
269    #[inline(always)]
270    #[cfg(target_pointer_width = "64")]
271    fn read_val(&self) -> u64 {
272        // Safety: reading `val` when `ptr` was written is sound on 64-bit —
273        // both fields are 8 bytes and we only inspect integer bits.
274        unsafe { self.val }
275    }
276
277    #[inline(always)]
278    #[cfg(not(target_pointer_width = "64"))]
279    fn read_val(&self) -> u64 {
280        self.val
281    }
282
283    fn get_kind(&self) -> u64 {
284        self.read_val() & Self::KIND_MASK
285    }
286
287    fn get_type(&self) -> u64 {
288        let val = self.read_val();
289        let typ = val & Self::TYPE_MASK;
290        let kind = val & Self::KIND_MASK;
291        match kind {
292            Self::STAIC_NODE | Self::OWNED_NODE => typ,
293            Self::STR_NODE | Self::RAWNUM_NODE | Self::ARR_NODE | Self::OBJ_NODE => {
294                typ & Self::KIND_MASK
295            }
296            Self::ROOT_NODE => typ & Self::KIND_MASK,
297            _ => unreachable!("unknown kind {kind}"),
298        }
299    }
300
301    fn unpack_dom_node(&self) -> NodeMeta {
302        debug_assert!(self.in_shared());
303        let val = self.read_val();
304        let idx = (val & Self::IDX_MASK) >> Self::KIND_BITS;
305        let len = val >> Self::LEN_OFFSET;
306        NodeMeta {
307            idx: idx as u32,
308            len: len as u32,
309        }
310    }
311
312    /// Recover the `*const Shared` from a root Meta node.
313    ///
314    /// On 64-bit: reads through the union `ptr` field (provenance preserved).
315    /// On 32-bit: recovers via `with_exposed_provenance`.
316    #[cfg(target_pointer_width = "64")]
317    fn unpack_root(&self) -> *const Shared {
318        debug_assert!(self.get_kind() == Self::ROOT_NODE);
319        unsafe { self.ptr.map_addr(|a| a & !(Self::ROOT_NODE as usize)) }
320    }
321
322    #[cfg(not(target_pointer_width = "64"))]
323    fn unpack_root(&self) -> *const Shared {
324        debug_assert!(self.get_kind() == Self::ROOT_NODE);
325        let addr = (self.val & !Self::ROOT_NODE) as usize;
326        std::ptr::with_exposed_provenance::<Shared>(addr)
327    }
328
329    fn has_strlen(&self) -> bool {
330        matches!(
331            self.get_type(),
332            Self::STR_NODE | Self::RAWNUM_NODE | Self::STATIC_STR
333        )
334    }
335
336    fn in_shared(&self) -> bool {
337        matches!(
338            self.get_type(),
339            Self::STR_NODE | Self::RAWNUM_NODE | Self::ARR_NODE | Self::OBJ_NODE
340        )
341    }
342
343    fn unpack_strlen(&self) -> usize {
344        debug_assert!(self.has_strlen());
345        (self.read_val() >> Self::LEN_OFFSET) as usize
346    }
347}
348
349struct NodeMeta {
350    idx: u32,
351    len: u32,
352}
353
354struct NodeInDom<'a> {
355    node: &'a Value,
356    dom: &'a Shared,
357}
358
359impl<'a> NodeInDom<'a> {
360    #[inline(always)]
361    fn get_inner(&self) -> ValueRefInner<'a> {
362        let typ = self.node.meta.get_type();
363        match typ {
364            Meta::STR_NODE => ValueRefInner::Str(self.unpack_str()),
365            Meta::RAWNUM_NODE => ValueRefInner::RawNum(self.unpack_str()),
366            Meta::ARR_NODE => ValueRefInner::Array(self.unpack_value_slice()),
367            Meta::OBJ_NODE => ValueRefInner::Object(self.unpack_pair_slice()),
368            _ => unreachable!("unknown type {typ} in dom"),
369        }
370    }
371
372    #[inline(always)]
373    fn unpack_str(&self) -> &'a str {
374        let len = self.node.meta.unpack_dom_node().len as usize;
375        let ptr = unsafe { self.node.data.dom_str.as_ptr() };
376        unsafe { str_from_raw_parts(ptr, len) }
377    }
378
379    #[inline(always)]
380    fn unpack_value_slice(&self) -> &'a [Value] {
381        let len = self.node.meta.unpack_dom_node().len as usize;
382        let elems = unsafe { self.node.data.arr_elems.as_ptr() };
383        unsafe { from_raw_parts(elems, len) }
384    }
385
386    #[inline(always)]
387    fn unpack_pair_slice(&self) -> &'a [Pair] {
388        let len = self.node.meta.unpack_dom_node().len as usize;
389        let pairs = unsafe { self.node.data.obj_pairs.as_ptr() };
390        unsafe { from_raw_parts(pairs, len) }
391    }
392}
393
394impl<'a> From<NodeInDom<'a>> for Value {
395    fn from(value: NodeInDom<'a>) -> Self {
396        Self {
397            meta: Meta::pack_shared(value.dom as *const _),
398            data: Data {
399                root: NonNull::from(value.node),
400            },
401        }
402    }
403}
404
405/// The value borrowed from the SharedDom
406enum ValueDetail<'a> {
407    Null,
408    Bool(bool),
409    Number(Number),
410    StaticStr(&'static str),
411    FastStr(&'a FastStr),
412    RawNumFasStr(&'a FastStr),
413    Array(&'a Arc<Vec<Value>>),
414    #[cfg(not(feature = "sort_keys"))]
415    Object(&'a Arc<AHashMap<FastStr, Value>>),
416    #[cfg(feature = "sort_keys")]
417    Object(&'a Arc<BTreeMap<FastStr, Value>>),
418    Root(NodeInDom<'a>),
419    NodeInDom(NodeInDom<'a>),
420    EmptyArray,
421    EmptyObject,
422}
423
424/// ValueRef is a immutable reference helper for `Value`.
425///
426/// # Example
427///
428/// ```
429/// use sonic_rs::{ValueRef, json, JsonValueTrait};
430///
431/// let v = json!({
432///    "name": "Xiaoming",
433///    "age": 18,
434/// });
435///
436/// match v.as_ref() {
437///     ValueRef::Object(obj) => {
438///        assert_eq!(obj.get(&"name").unwrap().as_str().unwrap(), "Xiaoming");
439///        assert_eq!(obj.get(&"age").unwrap().as_i64().unwrap(), 18);
440///    },
441///    _ => unreachable!(),
442/// }
443/// ```
444#[derive(Debug)]
445pub enum ValueRef<'a> {
446    Null,
447    Bool(bool),
448    Number(Number),
449    String(&'a str),
450    Array(&'a Array),
451    Object(&'a Object),
452}
453
454#[derive(Debug)]
455pub enum ValueRefInner<'a> {
456    Null,
457    Bool(bool),
458    Number(Number),
459    Str(&'a str),
460    RawNum(&'a str),
461    Array(&'a [Value]),
462    Object(&'a [Pair]),
463    #[cfg(not(feature = "sort_keys"))]
464    ObjectOwned(&'a Arc<AHashMap<FastStr, Value>>),
465    #[cfg(feature = "sort_keys")]
466    ObjectOwned(&'a Arc<BTreeMap<FastStr, Value>>),
467    EmptyArray,
468    EmptyObject,
469}
470
471impl<'a> From<&'a [Pair]> for Value {
472    fn from(value: &'a [Pair]) -> Self {
473        #[cfg(not(feature = "sort_keys"))]
474        let mut newd = AHashMap::with_capacity(value.len());
475        #[cfg(feature = "sort_keys")]
476        let mut newd = BTreeMap::new();
477
478        for (k, v) in value {
479            if let Some(k) = k.as_str() {
480                newd.insert(FastStr::new(k), v.clone());
481            }
482        }
483
484        Self {
485            meta: Meta::new(Meta::OBJ_MUT),
486            data: Data {
487                obj_own: ManuallyDrop::new(Arc::new(newd)),
488            },
489        }
490    }
491}
492
493impl Drop for Value {
494    fn drop(&mut self) {
495        if self.meta.get_kind() == Meta::STAIC_NODE || self.meta.in_shared() {
496            return;
497        }
498        // Safety: each arm accesses the Data union field matching the Meta type tag
499        match self.meta.get_type() {
500            Meta::FASTSTR | Meta::RAWNUM_FASTSTR => unsafe {
501                ManuallyDrop::drop(&mut self.data.str_own)
502            },
503            Meta::ARR_MUT => unsafe { ManuallyDrop::drop(&mut self.data.arr_own) },
504            Meta::OBJ_MUT => unsafe { ManuallyDrop::drop(&mut self.data.obj_own) },
505            Meta::ROOT_NODE => {
506                let dom = self.meta.unpack_root();
507                drop(unsafe { Arc::from_raw(dom) });
508            }
509            _ => unreachable!("should not be dropped"),
510        }
511    }
512}
513
514pub(crate) enum ValueMut<'a> {
515    Null,
516    Bool,
517    Number,
518    Str,
519    RawNum,
520    Array(&'a mut Vec<Value>),
521    #[cfg(not(feature = "sort_keys"))]
522    Object(&'a mut AHashMap<FastStr, Value>),
523    #[cfg(feature = "sort_keys")]
524    Object(&'a mut BTreeMap<FastStr, Value>),
525}
526
527impl Value {
528    fn is_node_kind(&self) -> bool {
529        matches!(
530            self.meta.get_kind(),
531            Meta::ARR_NODE | Meta::OBJ_NODE | Meta::STR_NODE | Meta::RAWNUM_NODE
532        )
533    }
534
535    pub(crate) fn as_mut(&mut self) -> ValueMut<'_> {
536        let typ = self.meta.get_type();
537        match typ {
538            Meta::NULL => ValueMut::Null,
539            Meta::TRUE | Meta::FALSE => ValueMut::Bool,
540            Meta::F64 | Meta::I64 | Meta::U64 => ValueMut::Number,
541            Meta::STATIC_STR | Meta::STR_NODE | Meta::FASTSTR => ValueMut::Str,
542            Meta::RAWNUM_FASTSTR | Meta::RAWNUM_NODE => ValueMut::RawNum,
543            Meta::ARR_MUT => ValueMut::Array(unsafe { Arc::make_mut(&mut self.data.arr_own) }),
544            Meta::OBJ_MUT => ValueMut::Object(unsafe { Arc::make_mut(&mut self.data.obj_own) }),
545            Meta::ROOT_NODE | Meta::EMPTY_ARR | Meta::EMPTY_OBJ => {
546                /* convert to mutable */
547                self.to_mut();
548                self.as_mut()
549            }
550            _ => unreachable!("should not be access in mutable api"),
551        }
552    }
553    fn to_mut(&mut self) {
554        assert!(
555            !self.meta.in_shared(),
556            "chidlren in shared should not to mut"
557        );
558        match self.unpack_ref() {
559            ValueDetail::Root(indom) => match indom.node.meta.get_type() {
560                Meta::ARR_NODE => {
561                    let slice = indom.unpack_value_slice();
562                    *self = slice.into();
563                }
564                Meta::OBJ_NODE => {
565                    let slice = indom.unpack_pair_slice();
566                    *self = slice.into();
567                }
568                _ => {}
569            },
570            ValueDetail::EmptyArray => *self = Value::new_array_with(8),
571            ValueDetail::EmptyObject => *self = Value::new_object_with(8),
572            _ => {}
573        }
574    }
575
576    fn unpack_static_str(&self) -> &'static str {
577        debug_assert!(self.meta.get_type() == Meta::STATIC_STR);
578        let ptr = unsafe { self.data.static_str.as_ptr() };
579        let len = self.meta.unpack_strlen();
580        unsafe { from_utf8_unchecked(from_raw_parts(ptr, len)) }
581    }
582
583    fn forward_find_shared(current: *const Value, idx: usize) -> *const Shared {
584        // Navigate back from a child Value to the MetaNode at the start of the
585        // bump allocation. This requires exposed provenance because `current`
586        // typically has narrow provenance (from &Value indexing), but we need to
587        // access memory outside that provenance range (the MetaNode before it).
588        // The bump allocation's provenance was exposed in visit_root/visit_container_end.
589        let meta_addr = current.expose_provenance() - idx * size_of::<Value>();
590        let meta = std::ptr::with_exposed_provenance::<MetaNode>(meta_addr);
591        assert!(unsafe { (*meta).canary() });
592        unsafe { (*meta).shared }
593    }
594
595    fn unpack_shared(&self) -> &Shared {
596        assert!(self.is_node_kind());
597        unsafe {
598            let idx = self.meta.unpack_dom_node().idx;
599            let cur = self as *const _;
600            let shared: *const Shared = Self::forward_find_shared(cur, idx as usize);
601            // The shared pointer stored in MetaNode was written with full
602            // provenance from the Shared allocation, so it can be dereferenced
603            // directly.
604            &*shared
605        }
606    }
607
608    #[inline(always)]
609    fn get_enum(&self) -> ValueRefInner<'_> {
610        match self.unpack_ref() {
611            ValueDetail::Null => ValueRefInner::Null,
612            ValueDetail::Bool(b) => ValueRefInner::Bool(b),
613            ValueDetail::Number(n) => ValueRefInner::Number(n.clone()),
614            ValueDetail::StaticStr(s) => ValueRefInner::Str(s),
615            ValueDetail::FastStr(s) => ValueRefInner::Str(s.as_str()),
616            ValueDetail::RawNumFasStr(s) => ValueRefInner::RawNum(s.as_str()),
617            ValueDetail::Array(a) => ValueRefInner::Array(a),
618            #[cfg(not(feature = "sort_keys"))]
619            ValueDetail::Object(o) => ValueRefInner::ObjectOwned(o),
620            #[cfg(feature = "sort_keys")]
621            ValueDetail::Object(o) => ValueRefInner::ObjectOwned(o),
622            ValueDetail::Root(n) | ValueDetail::NodeInDom(n) => n.get_inner(),
623            ValueDetail::EmptyArray => ValueRefInner::EmptyArray,
624            ValueDetail::EmptyObject => ValueRefInner::EmptyObject,
625        }
626    }
627
628    #[inline(always)]
629    fn unpack_ref(&self) -> ValueDetail<'_> {
630        // Safety: each arm accesses the Data union field matching the Meta type tag
631        match self.meta.get_type() {
632            Meta::NULL => ValueDetail::Null,
633            Meta::TRUE => ValueDetail::Bool(true),
634            Meta::FALSE => ValueDetail::Bool(false),
635            Meta::STATIC_STR => ValueDetail::StaticStr(self.unpack_static_str()),
636            Meta::I64 => ValueDetail::Number(Number::from(unsafe { self.data.ival })),
637            Meta::U64 => ValueDetail::Number(Number::from(unsafe { self.data.uval })),
638            Meta::F64 => ValueDetail::Number(Number::try_from(unsafe { self.data.fval }).unwrap()),
639            Meta::EMPTY_ARR => ValueDetail::EmptyArray,
640            Meta::EMPTY_OBJ => ValueDetail::EmptyObject,
641            Meta::STR_NODE | Meta::RAWNUM_NODE | Meta::ARR_NODE | Meta::OBJ_NODE => {
642                ValueDetail::NodeInDom(NodeInDom {
643                    node: self,
644                    dom: self.unpack_shared(),
645                })
646            }
647            Meta::FASTSTR => ValueDetail::FastStr(unsafe { &self.data.str_own }),
648            Meta::RAWNUM_FASTSTR => ValueDetail::RawNumFasStr(unsafe { &self.data.str_own }),
649            Meta::ARR_MUT => ValueDetail::Array(unsafe { &self.data.arr_own }),
650            Meta::OBJ_MUT => ValueDetail::Object(unsafe { &self.data.obj_own }),
651            Meta::ROOT_NODE => ValueDetail::Root(NodeInDom {
652                node: unsafe { self.data.root.as_ref() },
653                dom: unsafe { &*self.meta.unpack_root() },
654            }),
655            _ => unreachable!("unknown type"),
656        }
657    }
658}
659
660unsafe impl Sync for Value {}
661unsafe impl Send for Value {}
662
663impl Clone for Value {
664    /// Clone the value, if the value is a root node, we will create a new allocator for it.
665    ///
666    /// # Example
667    ///
668    /// ```
669    /// use sonic_rs::json;
670    ///
671    /// let a = json!({"a": [1, 2, 3]});
672    /// assert_eq!(a, a.clone());
673    /// ```
674    fn clone(&self) -> Self {
675        match self.unpack_ref() {
676            ValueDetail::Root(indom) | ValueDetail::NodeInDom(indom) => Value::from(indom),
677            ValueDetail::Null => Value::new_null(),
678            ValueDetail::Bool(b) => Value::new_bool(b),
679            ValueDetail::Number(n) => n.into(),
680            ValueDetail::StaticStr(s) => Value::from_static_str(s),
681            ValueDetail::FastStr(s) => s.into(),
682            ValueDetail::RawNumFasStr(s) => Value::new_rawnum_faststr(s),
683            ValueDetail::Array(a) => a.clone().into(),
684            ValueDetail::Object(o) => o.clone().into(),
685            ValueDetail::EmptyArray => Value::new_array(),
686            ValueDetail::EmptyObject => Value::new_object(),
687        }
688    }
689}
690
691impl From<Arc<Vec<Value>>> for Value {
692    fn from(value: Arc<Vec<Value>>) -> Self {
693        Self {
694            meta: Meta::new(Meta::ARR_MUT),
695            data: Data {
696                arr_own: ManuallyDrop::new(value),
697            },
698        }
699    }
700}
701
702#[cfg(not(feature = "sort_keys"))]
703impl From<Arc<AHashMap<FastStr, Value>>> for Value {
704    fn from(value: Arc<AHashMap<FastStr, Value>>) -> Self {
705        Self {
706            meta: Meta::new(Meta::OBJ_MUT),
707            data: Data {
708                obj_own: ManuallyDrop::new(value),
709            },
710        }
711    }
712}
713
714#[cfg(feature = "sort_keys")]
715impl From<Arc<BTreeMap<FastStr, Value>>> for Value {
716    fn from(value: Arc<BTreeMap<FastStr, Value>>) -> Self {
717        Self {
718            meta: Meta::new(Meta::OBJ_MUT),
719            data: Data {
720                obj_own: ManuallyDrop::new(value),
721            },
722        }
723    }
724}
725
726impl Debug for Value {
727    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
728        write!(f, "{:?}", self.as_ref2())?;
729        Ok(())
730    }
731}
732
733impl Default for Value {
734    fn default() -> Self {
735        Value::new()
736    }
737}
738
739impl Value {
740    /// Convert into `Object`. If the value is not an object, return `None`.
741    #[inline]
742    pub fn into_object(self) -> Option<Object> {
743        if self.is_object() {
744            Some(Object(self))
745        } else {
746            None
747        }
748    }
749
750    /// Convert into `Array`. If the value is not an array, return `None`.
751    #[inline]
752    pub fn into_array(self) -> Option<Array> {
753        if self.is_array() {
754            Some(Array(self))
755        } else {
756            None
757        }
758    }
759}
760
761impl Display for Value {
762    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
763        write!(f, "{}", crate::to_string(self).expect("invalid value"))
764    }
765}
766
767impl Debug for Data {
768    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
769        // Safety: reading `parent` (u64) from the union is valid for any bit pattern
770        let parent = unsafe { self.parent };
771        match parent {
772            0 => write!(f, "parent: null"),
773            _ => write!(f, "parent: {parent}"),
774        }
775    }
776}
777
778impl super::value_trait::JsonValueTrait for Value {
779    type ValueType<'v>
780        = &'v Value
781    where
782        Self: 'v;
783
784    #[inline]
785    fn get_type(&self) -> JsonType {
786        let typ = match self.get_enum() {
787            ValueRefInner::Null => JsonType::Null,
788            ValueRefInner::Bool(_) => JsonType::Boolean,
789            ValueRefInner::Number(_) => JsonType::Number,
790            ValueRefInner::Str(_) => JsonType::String,
791            ValueRefInner::Array(_) => JsonType::Array,
792            ValueRefInner::Object(_) | ValueRefInner::ObjectOwned(_) => JsonType::Object,
793            ValueRefInner::RawNum(_) => JsonType::Number,
794            ValueRefInner::EmptyArray => JsonType::Array,
795            ValueRefInner::EmptyObject => JsonType::Object,
796        };
797        typ
798    }
799
800    #[inline]
801    fn as_number(&self) -> Option<Number> {
802        match self.get_enum() {
803            ValueRefInner::Number(s) => Some(s),
804            ValueRefInner::RawNum(s) => crate::from_str(s).ok(),
805            _ => None,
806        }
807    }
808
809    fn as_raw_number(&self) -> Option<RawNumber> {
810        match self.unpack_ref() {
811            ValueDetail::RawNumFasStr(s) => Some(RawNumber::from_faststr(s.clone())),
812            ValueDetail::NodeInDom(indom) | ValueDetail::Root(indom) => match indom.get_inner() {
813                ValueRefInner::RawNum(s) => Some(RawNumber::new(s)),
814                _ => None,
815            },
816            _ => None,
817        }
818    }
819
820    #[inline]
821    fn as_i64(&self) -> Option<i64> {
822        self.as_number().and_then(|num| num.as_i64())
823    }
824
825    #[inline]
826    fn as_u64(&self) -> Option<u64> {
827        self.as_number().and_then(|num| num.as_u64())
828    }
829
830    #[inline]
831    fn as_f64(&self) -> Option<f64> {
832        self.as_number().and_then(|num| num.as_f64())
833    }
834
835    #[inline]
836    fn as_bool(&self) -> Option<bool> {
837        match self.meta.get_type() {
838            Meta::TRUE => Some(true),
839            Meta::FALSE => Some(false),
840            _ => None,
841        }
842    }
843
844    #[inline]
845    fn as_str(&self) -> Option<&str> {
846        match self.as_ref2() {
847            ValueRefInner::Str(s) => Some(s),
848            _ => None,
849        }
850    }
851
852    #[inline]
853    fn pointer<P: IntoIterator>(&self, path: P) -> Option<Self::ValueType<'_>>
854    where
855        P::Item: Index,
856    {
857        let path = path.into_iter();
858        let mut value = self;
859        for index in path {
860            value = value.get(index)?;
861        }
862        Some(value)
863    }
864
865    #[inline]
866    fn get<I: Index>(&self, index: I) -> Option<Self::ValueType<'_>> {
867        index.value_index_into(self)
868    }
869}
870
871impl JsonContainerTrait for Value {
872    type ArrayType = Array;
873    type ObjectType = Object;
874
875    #[inline]
876    fn as_array(&self) -> Option<&Self::ArrayType> {
877        if self.is_array() {
878            Some(Self::ArrayType::ref_cast(self))
879        } else {
880            None
881        }
882    }
883
884    #[inline]
885    fn as_object(&self) -> Option<&Self::ObjectType> {
886        if self.is_object() {
887            Some(Self::ObjectType::ref_cast(self))
888        } else {
889            None
890        }
891    }
892}
893
894impl JsonValueMutTrait for Value {
895    type ValueType = Value;
896    type ArrayType = Array;
897    type ObjectType = Object;
898
899    #[inline]
900    fn as_object_mut(&mut self) -> Option<&mut Self::ObjectType> {
901        if self.is_object() {
902            self.to_mut();
903            Some(Self::ObjectType::ref_cast_mut(self))
904        } else {
905            None
906        }
907    }
908
909    #[inline]
910    fn as_array_mut(&mut self) -> Option<&mut Self::ArrayType> {
911        if self.is_array() {
912            self.to_mut();
913            Some(Self::ArrayType::ref_cast_mut(self))
914        } else {
915            None
916        }
917    }
918
919    #[inline]
920    fn pointer_mut<P: IntoIterator>(&mut self, path: P) -> Option<&mut Self::ValueType>
921    where
922        P::Item: Index,
923    {
924        let mut path = path.into_iter();
925        let mut value = self.get_mut(path.next().unwrap())?;
926        for index in path {
927            value = value.get_mut(index)?;
928        }
929        Some(value)
930    }
931
932    #[inline]
933    fn get_mut<I: Index>(&mut self, index: I) -> Option<&mut Self::ValueType> {
934        index.index_into_mut(self)
935    }
936}
937
938impl Value {
939    const PADDING_SIZE: usize = 64;
940    pub(crate) const HEAD_NODE_COUNT: usize = 1;
941
942    /// Create a new `null` Value. It is also the default value of `Value`.
943    #[inline]
944    pub const fn new() -> Self {
945        Value {
946            // without shared allocator
947            meta: Meta::new(Meta::NULL),
948            data: Data { uval: 0 },
949        }
950    }
951
952    /// Create a reference `ValueRef` from a `&Value`.
953    ///
954    /// # Example
955    ///
956    /// ```
957    /// use sonic_rs::{ValueRef, json, JsonValueTrait};
958    ///
959    /// let v = json!({
960    ///    "name": "Xiaoming",
961    ///    "age": 18,
962    /// });
963    ///
964    /// match v.as_ref() {
965    ///     ValueRef::Object(obj) => {
966    ///        assert_eq!(obj.get(&"name").unwrap().as_str().unwrap(), "Xiaoming");
967    ///        assert_eq!(obj.get(&"age").unwrap().as_i64().unwrap(), 18);
968    ///    },
969    ///    _ => unreachable!(),
970    /// }
971    /// ```
972    #[inline]
973    pub fn as_ref(&self) -> ValueRef<'_> {
974        match self.get_enum() {
975            ValueRefInner::Null => ValueRef::Null,
976            ValueRefInner::Bool(b) => ValueRef::Bool(b),
977            ValueRefInner::Number(n) => ValueRef::Number(n),
978            ValueRefInner::Str(s) => ValueRef::String(s),
979            ValueRefInner::Array(_) | ValueRefInner::EmptyArray => {
980                ValueRef::Array(self.as_array().unwrap())
981            }
982            ValueRefInner::Object(_)
983            | ValueRefInner::EmptyObject
984            | ValueRefInner::ObjectOwned(_) => ValueRef::Object(self.as_object().unwrap()),
985            ValueRefInner::RawNum(raw) => {
986                crate::from_str(raw).map_or(ValueRef::Null, ValueRef::Number)
987            }
988        }
989    }
990
991    #[inline]
992    pub(crate) fn as_ref2(&self) -> ValueRefInner<'_> {
993        self.get_enum()
994    }
995
996    /// Create a new string Value from a `&'static str` with zero-copy.
997    ///
998    /// # Example
999    /// ```
1000    /// use sonic_rs::{array, JsonValueTrait, Value};
1001    ///
1002    /// let s = "hello";
1003    /// let v1 = Value::from_static_str("hello");
1004    /// assert_eq!(v1.as_str().unwrap().as_ptr(), s.as_ptr());
1005    ///
1006    /// let v2 = v1.clone();
1007    /// assert_eq!(v1.as_str().unwrap().as_ptr(), v2.as_str().unwrap().as_ptr());
1008    /// ```
1009    #[inline]
1010    pub fn from_static_str(val: &'static str) -> Self {
1011        if val.len() >= (u32::MAX as usize) {
1012            return Value {
1013                meta: Meta::new(Meta::FASTSTR),
1014                data: Data {
1015                    str_own: ManuallyDrop::new(Box::new(FastStr::new(val))),
1016                },
1017            };
1018        }
1019
1020        Value {
1021            meta: Meta::pack_static_str(Meta::STATIC_STR, val.len()),
1022            data: Data {
1023                static_str: NonNull::new(val.as_ptr() as *mut u8)
1024                    .expect("str::as_ptr() is non-null"),
1025            },
1026        }
1027    }
1028
1029    #[doc(hidden)]
1030    #[inline]
1031    pub fn new_u64(val: u64) -> Self {
1032        Value {
1033            meta: Meta::new(Meta::U64),
1034            data: Data { uval: val },
1035        }
1036    }
1037
1038    #[doc(hidden)]
1039    #[inline]
1040    pub fn new_i64(ival: i64) -> Self {
1041        Value {
1042            meta: Meta::new(Meta::I64),
1043            data: Data { ival },
1044        }
1045    }
1046
1047    #[doc(hidden)]
1048    #[inline]
1049    pub(crate) fn new_f64_unchecked(fval: f64) -> Self {
1050        debug_assert!(fval.is_finite(), "f64 must be finite");
1051        Value {
1052            meta: Meta::new(Meta::F64),
1053            data: Data { fval },
1054        }
1055    }
1056
1057    #[doc(hidden)]
1058    #[inline]
1059    pub fn new_f64(fval: f64) -> Option<Self> {
1060        if fval.is_finite() {
1061            Some(Value {
1062                meta: Meta::new(Meta::F64),
1063                data: Data { fval },
1064            })
1065        } else {
1066            None
1067        }
1068    }
1069
1070    #[doc(hidden)]
1071    #[inline]
1072    pub fn new_null() -> Self {
1073        Value {
1074            meta: Meta::new(Meta::NULL),
1075            data: Data { uval: 0 },
1076        }
1077    }
1078
1079    #[doc(hidden)]
1080    #[inline]
1081    pub const fn new_array() -> Self {
1082        Value {
1083            meta: Meta::new(Meta::EMPTY_ARR),
1084            data: Data { uval: 0 },
1085        }
1086    }
1087
1088    #[doc(hidden)]
1089    #[inline]
1090    pub const fn new_object() -> Self {
1091        Value {
1092            meta: Meta::new(Meta::EMPTY_OBJ),
1093            data: Data { uval: 0 },
1094        }
1095    }
1096
1097    #[doc(hidden)]
1098    #[inline]
1099    pub fn new_array_with(capacity: usize) -> Self {
1100        let arr_own = ManuallyDrop::new(Arc::new(Vec::<Value>::with_capacity(capacity)));
1101        Value {
1102            meta: Meta::new(Meta::ARR_MUT),
1103            data: Data { arr_own },
1104        }
1105    }
1106
1107    #[doc(hidden)]
1108    #[inline]
1109    pub fn new_bool(val: bool) -> Self {
1110        Value {
1111            meta: Meta::new(if val { Meta::TRUE } else { Meta::FALSE }),
1112            data: Data { uval: 0 },
1113        }
1114    }
1115
1116    #[doc(hidden)]
1117    #[inline]
1118    pub fn pack_str(kind: u64, idx: usize, val: &str) -> Self {
1119        let node_idx = idx as u32;
1120        // we check the json length when parsing, so val.len() should always be less than u32::MAX
1121        Value {
1122            meta: Meta::pack_dom_node(kind, node_idx, val.len() as u32),
1123            data: Data {
1124                dom_str: NonNull::new(val.as_ptr() as *mut _).expect("str::as_ptr() is non-null"),
1125            },
1126        }
1127    }
1128
1129    #[inline]
1130    pub(crate) fn new_rawnum_faststr(num: &FastStr) -> Self {
1131        let str_own = ManuallyDrop::new(Box::new(num.clone()));
1132        Value {
1133            meta: Meta::new(Meta::RAWNUM_FASTSTR),
1134            data: Data { str_own },
1135        }
1136    }
1137
1138    #[inline]
1139    pub(crate) fn new_rawnum(num: &str) -> Self {
1140        let str_own = ManuallyDrop::new(Box::new(FastStr::new(num)));
1141        Value {
1142            meta: Meta::new(Meta::RAWNUM_FASTSTR),
1143            data: Data { str_own },
1144        }
1145    }
1146
1147    pub(crate) fn len(&self) -> usize {
1148        match self.as_ref2() {
1149            ValueRefInner::Array(arr) => arr.len(),
1150            ValueRefInner::Object(obj) => obj.len(),
1151            ValueRefInner::Str(s) => s.len(),
1152            _ => 0,
1153        }
1154    }
1155
1156    pub(crate) fn as_value_slice(&self) -> Option<&[Value]> {
1157        match self.as_ref2() {
1158            ValueRefInner::Array(s) => Some(s),
1159            ValueRefInner::EmptyArray => Some(&[]),
1160            _ => None,
1161        }
1162    }
1163
1164    pub(crate) fn as_obj_len(&self) -> usize {
1165        match self.as_ref2() {
1166            ValueRefInner::Object(s) => s.len(),
1167            ValueRefInner::EmptyObject => 0,
1168            ValueRefInner::ObjectOwned(s) => s.len(),
1169            _ => unreachable!("value is not object"),
1170        }
1171    }
1172
1173    #[doc(hidden)]
1174    #[inline]
1175    pub fn copy_str(val: &str) -> Self {
1176        let str_own = ManuallyDrop::new(Box::new(FastStr::new(val)));
1177        Value {
1178            meta: Meta::new(Meta::FASTSTR),
1179            data: Data { str_own },
1180        }
1181    }
1182
1183    #[doc(hidden)]
1184    #[inline]
1185    pub fn copy_str_in(kind: u64, val: &str, idx: usize, shared: &mut Shared) -> Self {
1186        let str = shared.get_alloc().alloc_str(val);
1187        let node_idx = idx as u32;
1188        // we check the json length when parsing, so val.len() should always be less than u32::MAX
1189        Value {
1190            meta: Meta::pack_dom_node(kind, node_idx, str.len() as u32),
1191            data: Data {
1192                dom_str: NonNull::new(str.as_ptr() as *mut _).expect("str::as_ptr() is non-null"),
1193            },
1194        }
1195    }
1196
1197    #[doc(hidden)]
1198    #[inline]
1199    pub fn new_faststr(val: FastStr) -> Self {
1200        let str_own = ManuallyDrop::new(Box::new(val));
1201        Value {
1202            meta: Meta::new(Meta::FASTSTR),
1203            data: Data { str_own },
1204        }
1205    }
1206
1207    #[doc(hidden)]
1208    pub fn new_object_with(
1209        #[cfg(not(feature = "sort_keys"))] capacity: usize,
1210        #[cfg(feature = "sort_keys")] _: usize,
1211    ) -> Self {
1212        let obj_own = ManuallyDrop::new(Arc::new(
1213            #[cfg(not(feature = "sort_keys"))]
1214            AHashMap::with_capacity(capacity),
1215            #[cfg(feature = "sort_keys")]
1216            BTreeMap::new(),
1217        ));
1218        Value {
1219            meta: Meta::new(Meta::OBJ_MUT),
1220            data: Data { obj_own },
1221        }
1222    }
1223
1224    pub(crate) fn get_index(&self, index: usize) -> Option<&Self> {
1225        debug_assert!(self.is_array(), "{self:?}");
1226        if let ValueRefInner::Array(s) = self.as_ref2() {
1227            if index < s.len() {
1228                return Some(&s[index]);
1229            }
1230        }
1231        None
1232    }
1233
1234    pub(crate) fn get_index_mut(&mut self, index: usize) -> Option<&mut Self> {
1235        debug_assert!(self.is_array());
1236        if let ValueMut::Array(s) = self.as_mut() {
1237            if index < s.len() {
1238                return Some(&mut s[index]);
1239            }
1240        }
1241        None
1242    }
1243
1244    #[inline]
1245    pub(crate) fn get_key(&self, key: &str) -> Option<&Self> {
1246        self.get_key_value(key).map(|(_, v)| v)
1247    }
1248
1249    pub(crate) fn get_key_value(&self, key: &str) -> Option<(&str, &Self)> {
1250        debug_assert!(self.is_object());
1251        let ref_inner = self.as_ref2();
1252        if let ValueRefInner::Object(kv) = ref_inner {
1253            for (k, v) in kv {
1254                let k = k.as_str().expect("key is not string");
1255                if k == key {
1256                    return Some((k, v));
1257                }
1258            }
1259        } else if let ValueRefInner::ObjectOwned(kv) = ref_inner {
1260            if let Some((k, v)) = kv.get_key_value(key) {
1261                return Some((k.as_str(), v));
1262            }
1263        }
1264        None
1265    }
1266
1267    #[inline]
1268    pub(crate) fn get_key_mut(&mut self, key: &str) -> Option<&mut Self> {
1269        if let ValueMut::Object(kv) = self.as_mut() {
1270            if let Some(v) = kv.get_mut(key) {
1271                return Some(v);
1272            }
1273        }
1274        None
1275    }
1276
1277    #[inline]
1278    pub(crate) fn capacity(&self) -> usize {
1279        debug_assert!(self.is_object() || self.is_array());
1280        match self.unpack_ref() {
1281            ValueDetail::Array(arr) => arr.capacity(),
1282            #[cfg(not(feature = "sort_keys"))]
1283            ValueDetail::Object(obj) => obj.capacity(),
1284            #[cfg(feature = "sort_keys")]
1285            ValueDetail::Object(obj) => obj.len(),
1286            ValueDetail::NodeInDom(indom) | ValueDetail::Root(indom) => {
1287                if self.is_object() {
1288                    indom.unpack_pair_slice().len()
1289                } else {
1290                    indom.unpack_value_slice().len()
1291                }
1292            }
1293            ValueDetail::EmptyArray | ValueDetail::EmptyObject => 0,
1294            _ => unreachable!("value is not array or object"),
1295        }
1296    }
1297
1298    #[inline]
1299    pub(crate) fn clear(&mut self) {
1300        debug_assert!(self.is_object() || self.is_array());
1301        match self.as_mut() {
1302            ValueMut::Array(arr) => arr.clear(),
1303            ValueMut::Object(obj) => obj.clear(),
1304            _ => unreachable!("value is not array or object"),
1305        }
1306    }
1307
1308    #[inline]
1309    pub(crate) fn remove_index(&mut self, index: usize) -> Value {
1310        debug_assert!(self.is_array());
1311        match self.as_mut() {
1312            ValueMut::Array(arr) => arr.remove(index),
1313            _ => unreachable!("value is not array"),
1314        }
1315    }
1316
1317    #[inline]
1318    pub(crate) fn remove_key(&mut self, k: &str) -> Option<Value> {
1319        debug_assert!(self.is_object());
1320        match self.as_mut() {
1321            ValueMut::Object(obj) => obj.remove(k),
1322            _ => unreachable!("value is not object"),
1323        }
1324    }
1325
1326    /// Take the value from the node, and set the node as a empty node.
1327    /// Take will creat a new root node.
1328    ///
1329    /// # Examples
1330    /// ```
1331    /// use sonic_rs::json;
1332    /// use sonic_rs::JsonValueTrait;
1333    ///
1334    /// let mut value = json!({"a": 123});
1335    /// assert_eq!(value.take()["a"], 123);
1336    /// assert!(value.is_null());
1337    ///
1338    /// let mut value = json!(null);
1339    /// assert!(value.take().is_null());
1340    /// assert!(value.is_null());
1341    /// ```
1342    #[inline]
1343    pub fn take(&mut self) -> Self {
1344        std::mem::take(self)
1345    }
1346
1347    #[inline]
1348    pub(crate) fn reserve<T>(&mut self, additional: usize) {
1349        debug_assert!(self.is_object() || self.is_array());
1350        debug_assert!(size_of::<T>() == size_of::<Value>() || size_of::<T>() == size_of::<Pair>());
1351        match self.as_mut() {
1352            ValueMut::Array(arr) => arr.reserve(additional),
1353            #[cfg(not(feature = "sort_keys"))]
1354            ValueMut::Object(obj) => obj.reserve(additional),
1355            #[cfg(feature = "sort_keys")]
1356            ValueMut::Object(_) => {}
1357            _ => unreachable!("value is not array or object"),
1358        }
1359    }
1360
1361    #[doc(hidden)]
1362    #[inline]
1363    pub fn append_value(&mut self, val: Value) -> &mut Value {
1364        debug_assert!(self.is_array());
1365        match self.as_mut() {
1366            ValueMut::Array(arr) => {
1367                arr.push(val);
1368                let len = arr.len();
1369                &mut arr[len - 1]
1370            }
1371            _ => unreachable!("value is not array"),
1372        }
1373    }
1374
1375    #[doc(hidden)]
1376    #[inline]
1377    pub fn insert(&mut self, key: &str, val: Value) -> &mut Value {
1378        debug_assert!(self.is_object());
1379        match self.as_mut() {
1380            ValueMut::Object(obj) => {
1381                obj.insert(FastStr::new(key), val);
1382                obj.get_mut(key).unwrap()
1383            }
1384            _ => unreachable!("value is not object"),
1385        }
1386    }
1387
1388    #[inline]
1389    pub(crate) fn pop(&mut self) -> Option<Value> {
1390        debug_assert!(self.is_array());
1391        match self.as_mut() {
1392            ValueMut::Array(arr) => arr.pop(),
1393            _ => unreachable!("value is not object"),
1394        }
1395    }
1396
1397    #[inline(never)]
1398    pub(crate) fn parse_with_padding(&mut self, json: &[u8], cfg: DeserializeCfg) -> Result<usize> {
1399        // allocate the padding buffer for the input json
1400        let mut shared = Arc::new(Shared::default());
1401        // Expose Arc allocation provenance (header + data) so that
1402        // Arc::increment_strong_count in pack_shared can recover it
1403        // via with_exposed_provenance.
1404        Arc::as_ptr(&shared).expose_provenance();
1405        let mut buffer = Vec::with_capacity(json.len() + Self::PADDING_SIZE);
1406        buffer.extend_from_slice(json);
1407        buffer.extend_from_slice(&b"x\"x"[..]);
1408        buffer.extend_from_slice(&[0; 61]);
1409
1410        let smut = Arc::get_mut(&mut shared).unwrap();
1411        let slice = PaddedSliceRead::new(buffer.as_mut_slice(), json);
1412        let mut parser = Parser::new(slice).with_config(cfg);
1413        let mut vis = DocumentVisitor::new(json.len(), smut);
1414        parser.parse_dom(&mut vis, None)?;
1415        let idx = parser.read.index();
1416
1417        // NOTE: root node should is the first node
1418        *self = unsafe { vis.root.as_ref().clone() };
1419        smut.set_json(buffer);
1420        Ok(idx)
1421    }
1422
1423    #[inline(never)]
1424    pub(crate) fn parse_without_padding<'de, R: Reader<'de>>(
1425        &mut self,
1426        shared: &mut Shared,
1427        strbuf: &mut Vec<u8>,
1428        parser: &mut Parser<R>,
1429    ) -> Result<()> {
1430        let remain_len = parser.read.remain();
1431        let mut vis = DocumentVisitor::new(remain_len, shared);
1432        parser.parse_dom(&mut vis, Some(strbuf))?;
1433        *self = unsafe { vis.root.as_ref().clone() };
1434        Ok(())
1435    }
1436}
1437
1438// a simple wrapper for visitor
1439pub(crate) struct DocumentVisitor<'a> {
1440    // Store as raw pointer to avoid Stacked Borrows invalidation:
1441    // storing `&'a mut Shared` and later creating `*const Shared` from it
1442    // produces a tag that gets invalidated by subsequent mutable accesses.
1443    pub(crate) shared: *mut Shared,
1444    pub(crate) buf: TlsBuf,
1445    pub(crate) parent: usize,
1446    pub(crate) nodes_start: usize,
1447    pub(crate) root: NonNull<Value>,
1448    _marker: std::marker::PhantomData<&'a mut Shared>,
1449}
1450
1451impl<'a> DocumentVisitor<'a> {
1452    fn new(json_len: usize, shared: &'a mut Shared) -> Self {
1453        // optimize: use a pre-allocated vec.
1454        // If json is valid, the max number of value nodes should be
1455        // half of the valid json length + 2. like as [1,2,3,1,2,3...]
1456        // if the capacity is not enough, we will return a error.
1457        let max_len = (json_len / 2) + 2;
1458        let buf = TlsBuf::with_capacity(max_len);
1459        let shared = shared as *mut Shared;
1460        // Expose provenance so that forward_find_shared / unpack_shared can
1461        // recover the Shared pointer via with_exposed_provenance.
1462        (shared as *const Shared).expose_provenance();
1463        DocumentVisitor {
1464            shared,
1465            buf,
1466            parent: 0,
1467            nodes_start: 0,
1468            root: NonNull::dangling(),
1469            _marker: std::marker::PhantomData,
1470        }
1471    }
1472
1473    fn nodes(&mut self) -> &mut Vec<ManuallyDrop<Value>> {
1474        self.buf.as_vec_mut()
1475    }
1476
1477    fn index(&mut self) -> usize {
1478        self.nodes().len() - self.parent
1479    }
1480}
1481
1482#[repr(C)]
1483struct MetaNode {
1484    shared: *const Shared,
1485    canary: u64,
1486}
1487
1488const _: () = assert!(
1489    std::mem::size_of::<MetaNode>() == std::mem::size_of::<Value>(),
1490    "MetaNode and Value must have the same size for transmute safety"
1491);
1492
1493impl MetaNode {
1494    fn new(shared: *const Shared) -> Self {
1495        let canary = b"SONICRS\0";
1496        MetaNode {
1497            shared,
1498            canary: u64::from_ne_bytes(*canary),
1499        }
1500    }
1501
1502    fn canary(&self) -> bool {
1503        self.canary == u64::from_ne_bytes(*b"SONICRS\0")
1504    }
1505}
1506
1507impl<'a> DocumentVisitor<'a> {
1508    fn visit_container_start(&mut self, kind: u64) -> bool {
1509        let ret = self.push_node(Value {
1510            meta: Meta::pack_dom_node(kind, 0, 0), // update when array ending
1511            data: Data {
1512                parent: self.parent as u64, // record the old parent offset
1513            },
1514        });
1515        let len = self.nodes().len();
1516        self.parent = len - 1;
1517        ret
1518    }
1519
1520    // the array and object's logic is same.
1521    fn visit_container_end(&mut self, kind: u64, len: usize) -> bool {
1522        let vis = self;
1523        let parent = vis.parent;
1524        let old = unsafe { vis.nodes()[parent].data.parent as usize };
1525
1526        vis.parent = old;
1527        if len == 0 {
1528            let container = &mut vis.nodes()[parent];
1529            container.meta = Meta::new(if kind == Meta::OBJ_NODE {
1530                Meta::EMPTY_OBJ
1531            } else {
1532                Meta::EMPTY_ARR
1533            });
1534            return true;
1535        }
1536        unsafe {
1537            // not use `len` in here
1538            let visited_children = &vis.nodes()[(parent + 1)..];
1539            let real_count = visited_children.len() + Value::HEAD_NODE_COUNT;
1540            let layout = Layout::array::<Value>(real_count).unwrap();
1541            let hdr =
1542                (*vis.shared).get_alloc().alloc_layout(layout).as_ptr() as *mut ManuallyDrop<Value>;
1543
1544            // Expose provenance so forward_find_shared can navigate back via
1545            // with_exposed_provenance
1546            (hdr as *const ManuallyDrop<Value>).expose_provenance();
1547
1548            // copy visited nodes into document
1549            let visited_children = &vis.nodes()[(parent + 1)..];
1550            let src = visited_children.as_ptr();
1551            let elems = hdr.add(Value::HEAD_NODE_COUNT);
1552            std::ptr::copy_nonoverlapping(src, elems, visited_children.len());
1553
1554            // record the `Shared` pointer
1555            let meta = &mut *(hdr as *mut MetaNode);
1556            meta.shared = vis.shared as *const _;
1557            meta.canary = u64::from_ne_bytes(*b"SONICRS\0");
1558
1559            // update the container header
1560            let idx = (parent - vis.parent) as u32;
1561            let container = &mut vis.nodes()[parent];
1562            container.meta = Meta::pack_dom_node(kind, idx, len as u32);
1563            container.data.arr_elems = NonNull::new_unchecked(elems as *mut _);
1564            // must reset the length, because we copy the children into bumps
1565            vis.nodes().set_len(parent + 1);
1566        }
1567        true
1568    }
1569
1570    fn visit_root(&mut self) {
1571        // should alloc root node in the bump allocator
1572        let start = self.nodes_start;
1573        let ptr = self.shared as *const Shared;
1574        let tuple_ref =
1575            unsafe { (*self.shared).get_alloc() }.alloc((MetaNode::new(ptr), Value::default()));
1576
1577        // Expose provenance of the full (MetaNode, Value) allocation so that
1578        // forward_find_shared can navigate back to MetaNode via with_exposed_provenance.
1579        (tuple_ref as *const (MetaNode, Value)).expose_provenance();
1580
1581        // Copy source node to root using ptr::copy to preserve pointer provenance
1582        // in the Data union. Copying through data.uval (u64) would strip provenance.
1583        let src = &self.nodes()[start] as *const ManuallyDrop<Value> as *const Value;
1584        let dst = &mut tuple_ref.1 as *mut Value;
1585        unsafe { std::ptr::copy_nonoverlapping(src, dst, 1) };
1586        self.root = unsafe { NonNull::new_unchecked(dst) };
1587    }
1588
1589    #[inline(always)]
1590    fn push_node(&mut self, node: Value) -> bool {
1591        if self.nodes().len() == self.nodes().capacity() {
1592            false
1593        } else {
1594            self.nodes().push(ManuallyDrop::new(node));
1595            true
1596        }
1597    }
1598
1599    #[inline(always)]
1600    fn push_meta(&mut self, node: MetaNode) -> bool {
1601        if self.nodes().len() == self.nodes().capacity() {
1602            false
1603        } else {
1604            self.nodes().push(ManuallyDrop::new(unsafe {
1605                transmute::<MetaNode, Value>(node)
1606            }));
1607            true
1608        }
1609    }
1610}
1611
1612impl<'de, 'a> JsonVisitor<'de> for DocumentVisitor<'a> {
1613    #[inline(always)]
1614    fn visit_dom_start(&mut self) -> bool {
1615        let shared = self.shared as *const Shared;
1616        self.push_meta(MetaNode::new(shared));
1617        self.nodes_start = self.nodes().len();
1618        assert_eq!(self.nodes().len(), 1);
1619        true
1620    }
1621
1622    #[inline(always)]
1623    fn visit_bool(&mut self, val: bool) -> bool {
1624        self.push_node(Value::new_bool(val))
1625    }
1626
1627    #[inline(always)]
1628    fn visit_f64(&mut self, val: f64) -> bool {
1629        let node = Value::new_f64_unchecked(val);
1630        self.push_node(node)
1631    }
1632
1633    #[inline(always)]
1634    fn visit_raw_number(&mut self, val: &str) -> bool {
1635        let idx = self.index();
1636        let node = Value::copy_str_in(Meta::RAWNUM_NODE, val, idx, unsafe { &mut *self.shared });
1637        self.push_node(node)
1638    }
1639
1640    #[inline(always)]
1641    fn visit_borrowed_raw_number(&mut self, val: &str) -> bool {
1642        let idx = self.index();
1643        self.push_node(Value::pack_str(Meta::RAWNUM_NODE, idx, val))
1644    }
1645
1646    #[inline(always)]
1647    fn visit_i64(&mut self, val: i64) -> bool {
1648        self.push_node(Value::new_i64(val))
1649    }
1650
1651    #[inline(always)]
1652    fn visit_u64(&mut self, val: u64) -> bool {
1653        self.push_node(Value::new_u64(val))
1654    }
1655
1656    #[inline(always)]
1657    fn visit_array_start(&mut self, _hint: usize) -> bool {
1658        self.visit_container_start(Meta::ARR_NODE)
1659    }
1660
1661    #[inline(always)]
1662    fn visit_array_end(&mut self, len: usize) -> bool {
1663        self.visit_container_end(Meta::ARR_NODE, len)
1664    }
1665
1666    #[inline(always)]
1667    fn visit_object_start(&mut self, _hint: usize) -> bool {
1668        self.visit_container_start(Meta::OBJ_NODE)
1669    }
1670
1671    #[inline(always)]
1672    fn visit_object_end(&mut self, len: usize) -> bool {
1673        self.visit_container_end(Meta::OBJ_NODE, len)
1674    }
1675
1676    #[inline(always)]
1677    fn visit_null(&mut self) -> bool {
1678        self.push_node(Value::new_null())
1679    }
1680
1681    // this api should never used for parsing with padding buffer
1682    #[inline(always)]
1683    fn visit_str(&mut self, val: &str) -> bool {
1684        let idx = self.index();
1685        let node = Value::copy_str_in(Meta::STR_NODE, val, idx, unsafe { &mut *self.shared });
1686        self.push_node(node)
1687    }
1688
1689    #[inline(always)]
1690    fn visit_borrowed_str(&mut self, val: &'de str) -> bool {
1691        let idx = self.index();
1692        self.push_node(Value::pack_str(Meta::STR_NODE, idx, val))
1693    }
1694
1695    #[inline(always)]
1696    fn visit_key(&mut self, key: &str) -> bool {
1697        self.visit_str(key)
1698    }
1699
1700    #[inline(always)]
1701    fn visit_borrowed_key(&mut self, key: &'de str) -> bool {
1702        self.visit_borrowed_str(key)
1703    }
1704
1705    fn visit_dom_end(&mut self) -> bool {
1706        self.visit_root();
1707        true
1708    }
1709}
1710
1711impl Serialize for Value {
1712    #[inline]
1713    fn serialize<S>(&self, serializer: S) -> std::result::Result<S::Ok, S::Error>
1714    where
1715        S: ::serde::Serializer,
1716    {
1717        match self.as_ref2() {
1718            ValueRefInner::Null => serializer.serialize_unit(),
1719            ValueRefInner::Bool(b) => serializer.serialize_bool(b),
1720            ValueRefInner::Number(n) => n.serialize(serializer),
1721            ValueRefInner::Str(s) => s.serialize(serializer),
1722            ValueRefInner::Array(a) => {
1723                let mut seq = tri!(serializer.serialize_seq(Some(a.len())));
1724                for n in a {
1725                    tri!(seq.serialize_element(n));
1726                }
1727                seq.end()
1728            }
1729            ValueRefInner::EmptyArray => serializer.serialize_seq(None)?.end(),
1730            ValueRefInner::EmptyObject => serializer.serialize_map(None)?.end(),
1731            ValueRefInner::Object(o) => {
1732                #[cfg(feature = "sort_keys")]
1733                {
1734                    // TODO: sort the keys use thread-local buffer
1735                    let mut kvs: Vec<&(Value, Value)> = o.iter().collect();
1736                    kvs.sort_by(|(k1, _), (k2, _)| k1.as_str().unwrap().cmp(k2.as_str().unwrap()));
1737                    let mut map = tri!(serializer.serialize_map(Some(kvs.len())));
1738                    for (k, v) in kvs {
1739                        tri!(map.serialize_key(k.as_str().unwrap()));
1740                        tri!(map.serialize_value(v));
1741                    }
1742                    map.end()
1743                }
1744                #[cfg(not(feature = "sort_keys"))]
1745                {
1746                    let entries = o.iter();
1747                    let mut map = tri!(serializer.serialize_map(Some(entries.len())));
1748                    for (k, v) in entries {
1749                        tri!(map.serialize_key(k.as_str().unwrap()));
1750                        tri!(map.serialize_value(v));
1751                    }
1752                    map.end()
1753                }
1754            }
1755            #[cfg(not(feature = "sort_keys"))]
1756            ValueRefInner::ObjectOwned(o) => {
1757                let mut map = tri!(serializer.serialize_map(Some(o.len())));
1758                for (k, v) in o.iter() {
1759                    tri!(map.serialize_key(k.as_str()));
1760                    tri!(map.serialize_value(v));
1761                }
1762                map.end()
1763            }
1764            #[cfg(feature = "sort_keys")]
1765            ValueRefInner::ObjectOwned(o) => {
1766                let mut map = tri!(serializer.serialize_map(Some(o.len())));
1767                for (k, v) in o.iter() {
1768                    tri!(map.serialize_key(k.as_str()));
1769                    tri!(map.serialize_value(v));
1770                }
1771                map.end()
1772            }
1773            ValueRefInner::RawNum(raw) => {
1774                use serde::ser::SerializeStruct;
1775
1776                use crate::serde::rawnumber::TOKEN;
1777                let mut struct_ = tri!(serializer.serialize_struct(TOKEN, 1));
1778                tri!(struct_.serialize_field(TOKEN, raw));
1779                struct_.end()
1780            }
1781        }
1782    }
1783}
1784
1785#[cfg(test)]
1786mod test {
1787    use super::*;
1788    #[cfg(feature = "sort_keys")]
1789    use crate::object;
1790    use crate::{error::make_error, from_slice, from_str, pointer, util::mock::MockString};
1791
1792    #[derive(serde::Serialize, serde::Deserialize, Debug, PartialEq)]
1793    struct ValueInStruct {
1794        val: Value,
1795    }
1796
1797    fn test_value_instruct(data: &str) -> Result<()> {
1798        if let Ok(val) = from_str::<Value>(data) {
1799            let valin = ValueInStruct { val: val.clone() };
1800            let out = crate::to_string(&valin)?;
1801            let valin2: ValueInStruct = from_str(&out).unwrap();
1802            if valin2.val != val {
1803                diff_json(data);
1804                return Err(make_error(format!(
1805                    "invalid result when test parse valid json to ValueInStruct {data}"
1806                )));
1807            }
1808        }
1809        Ok(())
1810    }
1811
1812    fn test_value(data: &str) -> Result<()> {
1813        let serde_value: serde_json::Result<serde_json::Value> = serde_json::from_str(data);
1814        let dom: Result<Value> = from_slice(data.as_bytes());
1815
1816        if let Ok(serde_value) = serde_value {
1817            let dom = dom.unwrap();
1818            let sonic_out = crate::to_string(&dom)?;
1819            let serde_value2: serde_json::Value = serde_json::from_str(&sonic_out).unwrap();
1820
1821            if serde_value == serde_value2 {
1822                test_value_instruct(data)?;
1823                Ok(())
1824            } else {
1825                diff_json(data);
1826                Err(make_error(format!("invalid result for valid json {data}")))
1827            }
1828        } else {
1829            if dom.is_err() {
1830                return Ok(());
1831            }
1832            let dom = dom.unwrap();
1833            Err(make_error(format!(
1834                "invalid result for invalid json {}, got {}",
1835                data,
1836                crate::to_string(&dom).unwrap(),
1837            )))
1838        }
1839    }
1840
1841    fn diff_json(data: &str) {
1842        let serde_value: serde_json::Value = serde_json::from_str(data).unwrap();
1843        let dom: Value = from_slice(data.as_bytes()).unwrap();
1844        let sonic_out = crate::to_string(&dom).unwrap();
1845        let serde_value2: serde_json::Value = serde_json::from_str(&sonic_out).unwrap();
1846        let expect = serde_json::to_string_pretty(&serde_value).unwrap();
1847        let got = serde_json::to_string_pretty(&serde_value2).unwrap();
1848
1849        fn write_to(file: &str, data: &str) -> std::io::Result<()> {
1850            use std::io::Write;
1851            let mut file = std::fs::File::create(file)?;
1852            file.write_all(data.as_bytes())?;
1853            Ok(())
1854        }
1855
1856        if serde_value != serde_value2 {
1857            write_to("got.json", &got).unwrap();
1858            write_to("expect.json", &expect).unwrap();
1859        }
1860    }
1861
1862    #[cfg(not(target_arch = "wasm32"))]
1863    fn test_value_file(path: &std::path::Path) {
1864        let data = std::fs::read_to_string(path).unwrap();
1865        assert!(test_value(&data).is_ok(), "failed json is {path:?}");
1866    }
1867
1868    #[test]
1869    fn test_node_basic() {
1870        // // Valid JSON object
1871        // let data = r#"{"name": "John", "age": 30}"#;
1872        // assert!(test_value(data).is_ok(), "failed json is {}", data);
1873
1874        // // Valid JSON array
1875        // let data = r#"[1, 2, 3]"#;
1876        // assert!(test_value(data).is_ok(), "failed json is {}", data);
1877
1878        // Valid JSON data with nested objects and arrays
1879        let data = r#"{
1880            "name": "John",
1881            "age": 30,
1882            "cars": [
1883                { "name": "Ford", "models": ["Fiesta", "Focus", "Mustang"] },
1884                { "name": "BMW", "models": ["320", "X3", "X5"] },
1885                { "name": "Fiat", "models": ["500", "Panda"] }
1886            ],
1887            "address": {
1888                "street": "Main Street",
1889                "city": "New York",
1890                "state": "NY",
1891                "zip": "10001"
1892            }
1893        }"#;
1894        assert!(test_value(data).is_ok(), "failed json is {data}");
1895
1896        // // Valid JSON data with escape characters
1897        // let data = r#"{
1898        //     "name": "John",
1899        //     "age": 30,
1900        //     "description": "He said, \"I'm coming home.\""
1901        // }"#;
1902        // assert!(test_value(data).is_ok(), "failed json is {}", data);
1903    }
1904
1905    #[test]
1906    #[cfg(not(target_arch = "wasm32"))]
1907    #[cfg(not(miri))]
1908    fn test_node_from_files3() {
1909        use std::fs::DirEntry;
1910        let path = env!("CARGO_MANIFEST_DIR").to_string() + "/benchmarks/benches/testdata/";
1911        println!("dir is {path}");
1912
1913        let mut files: Vec<DirEntry> = std::fs::read_dir(path)
1914            .unwrap()
1915            .filter_map(|e| e.ok())
1916            .filter(|e| e.file_type().ok().map(|t| t.is_file()).unwrap_or(false))
1917            .collect();
1918
1919        files.sort_by(|a, b| {
1920            a.metadata()
1921                .unwrap()
1922                .len()
1923                .cmp(&b.metadata().unwrap().len())
1924        });
1925
1926        for file in files {
1927            let path = file.path();
1928            if path.extension().unwrap_or_default() == "json" && !path.ends_with("canada.json") {
1929                println!(
1930                    "test json file: {:?},  {} bytes",
1931                    path,
1932                    file.metadata().unwrap().len()
1933                );
1934                test_value_file(&path)
1935            }
1936        }
1937    }
1938
1939    #[test]
1940    fn test_json_tralings() {
1941        let testdata = [
1942            "-0.99999999999999999xxx",
1943            "\"\"\"",
1944            "{} x",
1945            "\"xxxxx",
1946            r#""\uDBDD\u1DD000"#,
1947        ];
1948
1949        for data in testdata {
1950            let ret: Result<Value> = from_slice(data.as_bytes());
1951            assert!(ret.is_err(), "failed json is {data}");
1952        }
1953    }
1954
1955    #[test]
1956    fn test_parse_numbrs() {
1957        let testdata = [
1958            " 33.3333333043333333",
1959            " 33.3333333053333333 ",
1960            " 33.3333333043333333--",
1961            &f64::MAX.to_string(),
1962            &f64::MIN.to_string(),
1963            &u64::MAX.to_string(),
1964            &u64::MIN.to_string(),
1965            &i64::MIN.to_string(),
1966            &i64::MAX.to_string(),
1967        ];
1968        for data in testdata {
1969            test_value(data).unwrap();
1970        }
1971    }
1972
1973    #[cfg(not(feature = "utf8_lossy"))]
1974    #[test]
1975    fn test_parse_escaped() {
1976        let testdata = [
1977            r#""\\9,\ud9CC\u8888|""#,
1978            r#"{"\t:0000000006427[{\t:003E:[[{0.77":96}"#,
1979        ];
1980        for data in testdata {
1981            test_value(data).unwrap();
1982        }
1983    }
1984
1985    const TEST_JSON: &str = r#"{
1986        "bool": true,
1987        "int": -1,
1988        "uint": 0,
1989        "float": 1.1,
1990        "string": "hello",
1991        "array": [1,2,3],
1992        "object": {"a":"aaa"},
1993        "strempty": "",
1994        "objempty": {},
1995        "arrempty": []
1996    }"#;
1997
1998    #[test]
1999    fn test_value_is() {
2000        let value: Value = crate::from_str(TEST_JSON).unwrap();
2001        assert!(value.get("bool").is_boolean());
2002        assert!(value.get("bool").is_true());
2003        assert!(value.get("uint").is_u64());
2004        assert!(value.get("uint").is_number());
2005        assert!(value.get("int").is_i64());
2006        assert!(value.get("float").is_f64());
2007        assert!(value.get("string").is_str());
2008        assert!(value.get("array").is_array());
2009        assert!(value.get("object").is_object());
2010        assert!(value.get("strempty").is_str());
2011        assert!(value.get("objempty").is_object());
2012        assert!(value.get("arrempty").is_array());
2013    }
2014
2015    #[test]
2016    fn test_value_get() {
2017        let value: Value = crate::from_str(TEST_JSON).unwrap();
2018        assert_eq!(value.get("int").as_i64().unwrap(), -1);
2019        assert_eq!(value["array"].get(0).as_i64().unwrap(), 1);
2020
2021        assert_eq!(value.pointer(pointer!["array", 2]).as_u64().unwrap(), 3);
2022        assert_eq!(
2023            value.pointer(pointer!["object", "a"]).as_str().unwrap(),
2024            "aaa"
2025        );
2026        assert_eq!(value.pointer(pointer!["objempty", "a"]).as_str(), None);
2027
2028        assert_eq!(value.pointer(pointer!["arrempty", 1]).as_str(), None);
2029
2030        assert!(!value.pointer(pointer!["unknown"]).is_str());
2031    }
2032
2033    #[cfg(not(feature = "utf8_lossy"))]
2034    #[test]
2035    fn test_invalid_utf8() {
2036        use crate::{from_slice, from_slice_unchecked};
2037
2038        let data = [b'"', 0x80, 0x90, b'"'];
2039        let ret: Result<Value> = from_slice(&data);
2040        assert_eq!(
2041            ret.err().unwrap().to_string(),
2042            "Invalid UTF-8 characters in json at line 1 column 2\n\n\t\"��\"\n\t.^..\n"
2043        );
2044
2045        let dom: Result<Value> = unsafe { from_slice_unchecked(&data) };
2046        assert!(dom.is_ok(), "{}", dom.unwrap_err());
2047
2048        let data = [b'"', b'"', 0x80];
2049        let dom: Result<Value> = from_slice(&data);
2050        assert_eq!(
2051            dom.err().unwrap().to_string(),
2052            "Invalid UTF-8 characters in json at line 1 column 3\n\n\t\"\"�\n\t..^\n"
2053        );
2054
2055        let data = [0x80, b'"', b'"'];
2056        let dom: Result<Value> = unsafe { from_slice_unchecked(&data) };
2057        assert_eq!(
2058            dom.err().unwrap().to_string(),
2059            "Invalid JSON value at line 1 column 1\n\n\t�\"\"\n\t^..\n"
2060        );
2061    }
2062
2063    #[test]
2064    fn test_value_serde() {
2065        use serde::{Deserialize, Serialize};
2066
2067        use crate::{array, object};
2068        #[derive(Deserialize, Debug, Serialize, PartialEq)]
2069        struct Foo {
2070            value: Value,
2071            object: Object,
2072            array: Array,
2073        }
2074
2075        let foo: Foo = crate::from_str(&MockString::from(
2076            r#"
2077        {
2078            "value": "hello",
2079            "object": {"a": "b"},
2080            "array": [1,2,3]
2081        }"#,
2082        ))
2083        .unwrap();
2084
2085        assert_eq!(
2086            foo,
2087            Foo {
2088                value: Value::from("hello"),
2089                object: object! {"a": "b"},
2090                array: array![1, 2, 3],
2091            }
2092        );
2093
2094        let _ = crate::from_str::<Foo>(
2095            r#"{
2096                "value": "hello",
2097                "object": {"a": "b"},
2098                "array": [1,2,3
2099            }"#,
2100        )
2101        .unwrap_err();
2102    }
2103
2104    #[test]
2105    #[cfg(not(miri))]
2106    fn test_arbitrary_precision() {
2107        use crate::Deserializer;
2108
2109        let nums = [
2110            "-46333333333333333333333333333333.6",
2111            "43.420273000",
2112            "1e123",
2113            "0.001","0e+12","0.1e+12",
2114            "0", "0.0", "1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345e+1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345",
2115            "12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123",
2116         "1.23456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567e89012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123",
2117        "-0.000000023456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567e+89012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123",
2118        ];
2119
2120        for num in nums {
2121            let mut de = Deserializer::from_str(num).use_rawnumber();
2122            let value: Value = de.deserialize().unwrap();
2123            assert_eq!(value.as_raw_number().unwrap().as_str(), num);
2124            assert_eq!(value.to_string(), num);
2125        }
2126    }
2127
2128    #[cfg(feature = "sort_keys")]
2129    #[test]
2130    fn test_sort_keys() {
2131        struct Case<'a> {
2132            input: &'a str,
2133            output: &'a str,
2134        }
2135
2136        let cases = [
2137            Case {
2138                input: r#"{"b": 2,"bc":{"cb":1,"ca":"hello"},"a": 1}"#,
2139                output: r#"{"a":1,"b":2,"bc":{"ca":"hello","cb":1}}"#,
2140            },
2141            Case {
2142                input: r#"{"a":1}"#,
2143                output: r#"{"a":1}"#,
2144            },
2145            Case {
2146                input: r#"{"b": 2,"a": 1}"#,
2147                output: r#"{"a":1,"b":2}"#,
2148            },
2149            Case {
2150                input: "{}",
2151                output: "{}",
2152            },
2153            Case {
2154                input: r#"[{"b": 2,"c":{"cb":1,"ca":"hello"},"a": 1}, {"ab": 2,"aa": 1}]"#,
2155                output: r#"[{"a":1,"b":2,"c":{"ca":"hello","cb":1}},{"aa":1,"ab":2}]"#,
2156            },
2157        ];
2158
2159        for case in cases {
2160            let value: Value = crate::from_str(case.input).unwrap();
2161            assert_eq!(value.to_string(), case.output);
2162        }
2163    }
2164
2165    #[cfg(feature = "sort_keys")]
2166    #[test]
2167    fn test_sort_keys_owned() {
2168        let obj = object! {
2169            "b": 2,
2170            "bc": object! {
2171                "cb": 1,
2172                "ca": "hello",
2173            },
2174            "a": 1,
2175        };
2176
2177        let obj2 = object! {
2178            "a": 1,
2179            "b": 2,
2180            "bc": object! {
2181                "ca": "hello",
2182                "cb": 1,
2183            },
2184        };
2185
2186        assert_eq!(obj, obj2);
2187    }
2188
2189    #[test]
2190    fn test_issue_179_line_column() {
2191        let json = r#"
2192        {
2193            "key\nwith\nnewlines": "value",
2194            "another_key": [, 1, 2, 3]
2195        }
2196        "#;
2197        let err = crate::from_str::<Value>(json).unwrap_err();
2198        assert_eq!(err.line(), 4);
2199    }
2200}