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