Skip to main content

sonic_rs/lazyvalue/
owned.rs

1use std::{
2    fmt::{self, Debug, Display},
3    str::from_utf8_unchecked,
4    sync::atomic::{AtomicPtr, Ordering},
5};
6
7use faststr::FastStr;
8use ref_cast::RefCast;
9use serde::ser::{SerializeMap, SerializeStruct};
10
11use super::value::HasEsc;
12use crate::{
13    index::Index, input::JsonSlice, prelude::*, serde::Number, JsonType, JsonValueTrait, LazyValue,
14    RawNumber, Result,
15};
16
17/// OwnedLazyValue wrappers a unparsed raw JSON text. It is owned and support `Get, Set`
18///
19/// It can be converted from [`LazyValue`](crate::lazyvalue::LazyValue). It can be used for serde.
20///
21/// Default value is a raw JSON text `null`.
22///
23/// # Examples
24///
25/// ```
26/// use sonic_rs::{get, JsonValueTrait, OwnedLazyValue};
27///
28/// // get a lazyvalue from a json, the "a"'s value will not be parsed
29/// let input = r#"{
30///  "a": "hello world",
31///  "b": true,
32///  "c": [0, 1, 2],
33///  "d": {
34///     "sonic": "rs"
35///   }
36/// }"#;
37///
38/// let own_a = OwnedLazyValue::from(get(input, &["a"]).unwrap());
39/// let own_c = OwnedLazyValue::from(get(input, &["c"]).unwrap());
40///
41/// // use as_xx to get the parsed value
42/// assert_eq!(own_a.as_str().unwrap(), "hello world");
43/// assert_eq!(own_c.as_str(), None);
44/// assert!(own_c.is_array());
45/// ```
46///
47/// # Serde Examples
48///
49/// ```
50/// # use sonic_rs::{LazyValue, OwnedLazyValue};
51/// use serde::{Deserialize, Serialize};
52///
53/// #[derive(Debug, Deserialize, Serialize)]
54/// struct TestLazyValue<'a> {
55///     #[serde(borrow)]
56///     borrowed_lv: LazyValue<'a>,
57///     owned_lv: OwnedLazyValue,
58/// }
59///
60/// let input = r#"{ "borrowed_lv": "hello", "owned_lv": "world" }"#;
61///
62/// let data: TestLazyValue = sonic_rs::from_str(input).unwrap();
63/// assert_eq!(data.borrowed_lv.as_raw_str(), "\"hello\"");
64/// ```
65#[derive(Debug, Clone)]
66pub struct OwnedLazyValue(pub(crate) LazyPacked);
67
68impl Default for OwnedLazyValue {
69    fn default() -> Self {
70        Self(LazyPacked::Parsed(Parsed::Null))
71    }
72}
73
74impl OwnedLazyValue {
75    pub(crate) fn from_non_esc_str(raw: FastStr) -> Self {
76        Self(LazyPacked::NonEscStrRaw(raw))
77    }
78
79    pub(crate) fn from_faststr(str: FastStr) -> Self {
80        Self(LazyPacked::Parsed(Parsed::String(str)))
81    }
82}
83
84impl From<Number> for OwnedLazyValue {
85    fn from(number: Number) -> Self {
86        Self(LazyPacked::Parsed(Parsed::Number(number)))
87    }
88}
89
90impl From<Vec<(FastStr, OwnedLazyValue)>> for OwnedLazyValue {
91    fn from(v: Vec<(FastStr, OwnedLazyValue)>) -> Self {
92        Self(LazyPacked::Parsed(Parsed::LazyObject(v)))
93    }
94}
95
96impl From<Vec<OwnedLazyValue>> for OwnedLazyValue {
97    fn from(v: Vec<OwnedLazyValue>) -> Self {
98        Self(LazyPacked::Parsed(Parsed::LazyArray(v)))
99    }
100}
101
102impl From<bool> for OwnedLazyValue {
103    fn from(v: bool) -> Self {
104        Self(LazyPacked::Parsed(Parsed::Bool(v)))
105    }
106}
107
108impl From<()> for OwnedLazyValue {
109    fn from(_: ()) -> Self {
110        Self(LazyPacked::Parsed(Parsed::Null))
111    }
112}
113
114pub(crate) struct LazyRaw {
115    // the raw slice from origin json
116    pub(crate) raw: FastStr,
117    pub(crate) parsed: AtomicPtr<Parsed>,
118}
119
120impl Drop for LazyRaw {
121    fn drop(&mut self) {
122        let ptr = self.parsed.get_mut();
123        if !(*ptr).is_null() {
124            unsafe {
125                drop(Box::from_raw(*ptr));
126            }
127        }
128    }
129}
130
131impl Debug for LazyRaw {
132    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
133        let ptr = self.parsed.load(Ordering::Relaxed);
134        let s = if ptr.is_null() {
135            "<nill>".to_string()
136        } else {
137            format!("{:?}", unsafe { &*ptr })
138        };
139        f.debug_struct("LazyRaw")
140            .field("raw", &self.raw)
141            .field("parsed", &s)
142            .finish()
143    }
144}
145
146impl LazyRaw {
147    fn load(&self) -> Result<&Parsed> {
148        let ptr = self.parsed.load(Ordering::Acquire);
149        if !ptr.is_null() {
150            return Ok(unsafe { &*ptr });
151        }
152
153        let mut parser = crate::parser::Parser::new(crate::Read::from(&self.raw));
154        let mut strbuf: Vec<u8> = Vec::new();
155        let olv: OwnedLazyValue = parser.load_owned_lazyvalue(&mut strbuf)?;
156        let OwnedLazyValue(LazyPacked::Parsed(v)) = olv else {
157            unreachable!("must be lazy parsed");
158        };
159        let parsed = Box::into_raw(Box::new(v));
160        loop {
161            match self.parsed.compare_exchange_weak(
162                ptr,
163                parsed,
164                Ordering::AcqRel,
165                Ordering::Acquire,
166            ) {
167                // will free by drop
168                Ok(_) => return Ok(unsafe { &*parsed }),
169                Err(ptr) => {
170                    if ptr.is_null() {
171                        continue;
172                    }
173                    // # Safety
174                    // the pointer is immutable here, and we can drop it
175                    drop(unsafe { Box::from_raw(parsed) });
176                    return Ok(unsafe { &*ptr });
177                }
178            }
179        }
180    }
181
182    fn parse(&mut self) -> Result<Parsed> {
183        let ptr = self.parsed.get_mut();
184        if !(*ptr).is_null() {
185            let v = unsafe { Box::from_raw(*ptr) };
186            *ptr = std::ptr::null_mut();
187            return Ok(*v);
188        }
189
190        let mut parser = crate::parser::Parser::new(crate::Read::from(&self.raw));
191        let mut strbuf: Vec<u8> = Vec::new();
192        let olv: OwnedLazyValue = parser.load_owned_lazyvalue(&mut strbuf)?;
193        let OwnedLazyValue(LazyPacked::Parsed(v)) = olv else {
194            unreachable!("must be lazy parsed");
195        };
196        Ok(v)
197    }
198
199    fn get<I: Index>(&self, idx: I) -> Option<&OwnedLazyValue> {
200        match self.get_type() {
201            JsonType::Array if idx.as_index().is_some() => {
202                let parsed = self.load().ok()?;
203                parsed.get(idx)
204            }
205            JsonType::Object if idx.as_key().is_some() => {
206                let parsed = self.load().ok()?;
207                parsed.get(idx)
208            }
209            _ => None,
210        }
211    }
212
213    fn as_number(&self) -> Option<Number> {
214        match self.get_type() {
215            JsonType::Number => match self.load().ok()? {
216                Parsed::Number(n) => Some(n.clone()),
217                _ => None,
218            },
219            _ => None,
220        }
221    }
222
223    fn as_str(&self) -> Option<&str> {
224        match self.get_type() {
225            JsonType::String => match self.load().ok()? {
226                Parsed::String(s) => Some(s.as_str()),
227                _ => None,
228            },
229            _ => None,
230        }
231    }
232
233    fn as_raw_number(&self) -> Option<RawNumber> {
234        if self.raw.as_bytes()[0] == b'-' || self.raw.as_bytes()[0].is_ascii_digit() {
235            Some(RawNumber::from_faststr(self.raw.clone()))
236        } else {
237            None
238        }
239    }
240
241    fn get_type(&self) -> JsonType {
242        match self.raw.as_bytes()[0] {
243            b'-' | b'0'..=b'9' => JsonType::Number,
244            b'"' => JsonType::String,
245            b'[' => JsonType::Array,
246            b'{' => JsonType::Object,
247            _ => unreachable!("invalid raw json value"),
248        }
249    }
250
251    fn clone_lazyraw(&self) -> std::result::Result<LazyRaw, Parsed> {
252        let parsed = self.parsed.load(Ordering::Relaxed);
253        if parsed.is_null() {
254            Ok(LazyRaw {
255                raw: self.raw.clone(),
256                parsed: AtomicPtr::new(std::ptr::null_mut()),
257            })
258        } else {
259            // # Safety
260            // the pointer is immutable here, and we can clone it
261            Err(unsafe { (*parsed).clone() })
262        }
263    }
264}
265
266#[derive(Debug)]
267pub(crate) enum LazyPacked {
268    // raw value: number, maybe esc strings, raw object, raw array
269    Raw(LazyRaw),
270    // most JSON string without escaped chars, will also optimize serialize
271    NonEscStrRaw(FastStr),
272    Parsed(Parsed),
273}
274
275impl LazyPacked {}
276
277impl Clone for LazyPacked {
278    fn clone(&self) -> Self {
279        match self {
280            Self::Raw(raw) => match raw.clone_lazyraw() {
281                Ok(raw) => Self::Raw(raw),
282                Err(v) => Self::Parsed(v),
283            },
284            Self::NonEscStrRaw(s) => Self::NonEscStrRaw(s.clone()),
285            Self::Parsed(v) => Self::Parsed(v.clone()),
286        }
287    }
288}
289
290#[derive(Debug, Clone)]
291pub(crate) enum Parsed {
292    LazyObject(Vec<(FastStr, OwnedLazyValue)>),
293    LazyArray(Vec<OwnedLazyValue>),
294    String(FastStr),
295    Number(Number),
296    Null,
297    Bool(bool),
298}
299
300impl Parsed {
301    fn get_type(&self) -> JsonType {
302        match self {
303            Parsed::LazyObject(_) => JsonType::Object,
304            Parsed::LazyArray(_) => JsonType::Array,
305            Parsed::String(_) => JsonType::String,
306            Parsed::Number(_) => JsonType::Number,
307            Parsed::Null => JsonType::Null,
308            Parsed::Bool(_) => JsonType::Boolean,
309        }
310    }
311
312    fn get<I: Index>(&self, index: I) -> Option<&OwnedLazyValue> {
313        match self {
314            Parsed::LazyObject(obj) => {
315                if let Some(key) = index.as_key() {
316                    for (k, v) in obj {
317                        if k == key {
318                            return Some(v);
319                        }
320                    }
321                }
322                None
323            }
324            Parsed::LazyArray(arr) => {
325                if let Some(index) = index.as_index() {
326                    arr.get(index)
327                } else {
328                    None
329                }
330            }
331            _ => None,
332        }
333    }
334
335    fn get_mut<I: Index>(&mut self, index: I) -> Option<&mut OwnedLazyValue> {
336        match self {
337            Parsed::LazyObject(obj) => {
338                if let Some(key) = index.as_key() {
339                    for (k, v) in obj {
340                        if k == key {
341                            return Some(v);
342                        }
343                    }
344                }
345                None
346            }
347            Parsed::LazyArray(arr) => {
348                if let Some(index) = index.as_index() {
349                    arr.get_mut(index)
350                } else {
351                    None
352                }
353            }
354            _ => None,
355        }
356    }
357}
358
359impl JsonValueTrait for OwnedLazyValue {
360    type ValueType<'v> = &'v OwnedLazyValue;
361
362    fn as_bool(&self) -> Option<bool> {
363        if let LazyPacked::Parsed(Parsed::Bool(b)) = &self.0 {
364            Some(*b)
365        } else {
366            None
367        }
368    }
369
370    fn as_number(&self) -> Option<Number> {
371        match &self.0 {
372            LazyPacked::Parsed(Parsed::Number(n)) => Some(n.clone()),
373            LazyPacked::Raw(raw) => raw.as_number(),
374            _ => None,
375        }
376    }
377
378    fn as_raw_number(&self) -> Option<crate::RawNumber> {
379        match &self.0 {
380            LazyPacked::Raw(raw) => raw.as_raw_number(),
381            _ => None,
382        }
383    }
384
385    fn as_str(&self) -> Option<&str> {
386        match &self.0 {
387            LazyPacked::Parsed(Parsed::String(s)) => Some(s.as_str()),
388            LazyPacked::Raw(raw) => raw.as_str(),
389            LazyPacked::NonEscStrRaw(raw) => {
390                Some(unsafe { from_utf8_unchecked(&raw.as_bytes()[1..raw.len() - 1]) })
391            }
392            _ => None,
393        }
394    }
395
396    fn get_type(&self) -> JsonType {
397        match &self.0 {
398            LazyPacked::Parsed(v) => v.get_type(),
399            LazyPacked::Raw(raw) => raw.get_type(),
400            LazyPacked::NonEscStrRaw(_) => JsonType::String,
401        }
402    }
403
404    fn get<I: Index>(&self, index: I) -> Option<&OwnedLazyValue> {
405        match &self.0 {
406            LazyPacked::Parsed(v) => v.get(index),
407            LazyPacked::Raw(raw) => raw.get(index),
408            _ => None,
409        }
410    }
411
412    fn pointer<P: IntoIterator>(&self, path: P) -> Option<&OwnedLazyValue>
413    where
414        P::Item: Index,
415    {
416        let mut next = self;
417        for index in path {
418            next = match &next.0 {
419                LazyPacked::Parsed(v) => v.get(index),
420                LazyPacked::Raw(raw) => raw.get(index),
421                _ => None,
422            }?;
423        }
424        Some(next)
425    }
426}
427
428impl JsonValueMutTrait for OwnedLazyValue {
429    type ValueType = OwnedLazyValue;
430    type ArrayType = LazyArray;
431    type ObjectType = LazyObject;
432
433    fn as_object_mut(&mut self) -> Option<&mut LazyObject> {
434        if let LazyPacked::Raw(raw) = &mut self.0 {
435            if raw.get_type() == JsonType::Object {
436                let parsed = raw.parse().ok()?;
437                self.0 = LazyPacked::Parsed(parsed);
438            } else {
439                return None;
440            }
441        }
442
443        if let LazyPacked::Parsed(Parsed::LazyObject(_)) = &mut self.0 {
444            Some(LazyObject::ref_cast_mut(self))
445        } else {
446            None
447        }
448    }
449
450    fn as_array_mut(&mut self) -> Option<&mut LazyArray> {
451        if let LazyPacked::Raw(raw) = &mut self.0 {
452            if raw.get_type() == JsonType::Array {
453                let parsed = raw.parse().ok()?;
454                self.0 = LazyPacked::Parsed(parsed);
455            } else {
456                return None;
457            }
458        }
459
460        if let LazyPacked::Parsed(Parsed::LazyArray(_)) = &mut self.0 {
461            Some(LazyArray::ref_cast_mut(self))
462        } else {
463            None
464        }
465    }
466
467    fn get_mut<I: Index>(&mut self, index: I) -> Option<&mut OwnedLazyValue> {
468        if matches!(self.0, LazyPacked::Raw(_)) {
469            self.get_mut_from_raw(index)
470        } else if let LazyPacked::Parsed(parsed) = &mut self.0 {
471            parsed.get_mut(index)
472        } else {
473            None
474        }
475    }
476
477    fn pointer_mut<P: IntoIterator>(&mut self, path: P) -> Option<&mut OwnedLazyValue>
478    where
479        P::Item: Index,
480    {
481        let mut next = self;
482        for index in path {
483            if matches!(next.0, LazyPacked::Raw(_)) {
484                next = next.get_mut_from_raw(index)?;
485            } else {
486                next = match &mut next.0 {
487                    LazyPacked::Parsed(v) => v.get_mut(index),
488                    _ => None,
489                }?;
490            }
491        }
492        Some(next)
493    }
494}
495
496impl JsonContainerTrait for OwnedLazyValue {
497    type ArrayType = LazyArray;
498    type ObjectType = LazyObject;
499
500    #[inline]
501    fn as_array(&self) -> Option<&Self::ArrayType> {
502        let parsed = match &self.0 {
503            LazyPacked::Raw(raw) if raw.get_type() == JsonType::Array => raw.load().ok()?,
504            LazyPacked::Parsed(parsed) => parsed,
505            _ => return None,
506        };
507
508        if let Parsed::LazyArray(_) = parsed {
509            Some(LazyArray::ref_cast(self))
510        } else {
511            None
512        }
513    }
514
515    #[inline]
516    fn as_object(&self) -> Option<&Self::ObjectType> {
517        let parsed = match &self.0 {
518            LazyPacked::Raw(raw) if raw.get_type() == JsonType::Object => raw.load().ok()?,
519            LazyPacked::Parsed(parsed) => parsed,
520            _ => return None,
521        };
522
523        if let Parsed::LazyObject(_) = parsed {
524            Some(LazyObject::ref_cast(self))
525        } else {
526            None
527        }
528    }
529}
530
531impl OwnedLazyValue {
532    pub fn take(&mut self) -> Self {
533        std::mem::take(self)
534    }
535
536    pub(crate) fn new(raw: JsonSlice, status: HasEsc) -> Self {
537        let raw = match raw {
538            JsonSlice::Raw(r) => FastStr::new(unsafe { from_utf8_unchecked(r) }),
539            JsonSlice::FastStr(f) => f.clone(),
540        };
541
542        if status == HasEsc::None {
543            Self(LazyPacked::NonEscStrRaw(raw))
544        } else {
545            Self(LazyPacked::Raw(LazyRaw {
546                raw,
547                parsed: AtomicPtr::new(std::ptr::null_mut()),
548            }))
549        }
550    }
551
552    fn get_mut_from_raw<I: Index>(&mut self, index: I) -> Option<&mut Self> {
553        let raw = if let LazyPacked::Raw(raw) = &mut self.0 {
554            raw
555        } else {
556            return None;
557        };
558
559        match raw.get_type() {
560            JsonType::Array if index.as_index().is_some() => {
561                let parsed = raw.parse().ok()?;
562                *self = Self(LazyPacked::Parsed(parsed));
563            }
564            JsonType::Object if index.as_key().is_some() => {
565                let parsed = raw.parse().ok()?;
566                *self = Self(LazyPacked::Parsed(parsed));
567            }
568            _ => return None,
569        }
570
571        if let LazyPacked::Parsed(parsed) = &mut self.0 {
572            parsed.get_mut(index)
573        } else {
574            None
575        }
576    }
577}
578
579impl<'de> From<LazyValue<'de>> for OwnedLazyValue {
580    fn from(lv: LazyValue<'de>) -> Self {
581        let raw = lv.raw.as_faststr();
582        if lv.inner.no_escaped() && raw.as_bytes()[0] == b'"' {
583            return Self(LazyPacked::NonEscStrRaw(raw));
584        }
585
586        Self(LazyPacked::Raw(LazyRaw {
587            raw,
588            parsed: AtomicPtr::new(std::ptr::null_mut()),
589        }))
590    }
591}
592
593impl Display for OwnedLazyValue {
594    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
595        write!(f, "{:?}", crate::to_string(self))
596    }
597}
598
599impl serde::ser::Serialize for OwnedLazyValue {
600    fn serialize<S>(&self, serializer: S) -> std::result::Result<S::Ok, S::Error>
601    where
602        S: serde::Serializer,
603    {
604        match &self.0 {
605            LazyPacked::Raw(raw) => {
606                let raw = raw.raw.as_str();
607                let mut s = serializer.serialize_struct(super::TOKEN, 1)?;
608                // will directly write raw in `LazyValueStrEmitter::seriazlie_str`
609                s.serialize_field(super::TOKEN, raw)?;
610                s.end()
611            }
612            LazyPacked::NonEscStrRaw(raw) => {
613                let raw = raw.as_str();
614                let mut s = serializer.serialize_struct(super::TOKEN, 1)?;
615                // will directly write raw in `LazyValueStrEmitter::seriazlie_str`
616                s.serialize_field(super::TOKEN, raw)?;
617                s.end()
618            }
619            LazyPacked::Parsed(Parsed::LazyObject(vec)) => {
620                // if expected to be sort-keys, should use `sonic_rs::Value`
621                let mut map = serializer.serialize_map(Some(vec.len()))?;
622                for (k, v) in vec {
623                    map.serialize_entry(k, v)?;
624                }
625                map.end()
626            }
627            LazyPacked::Parsed(Parsed::LazyArray(vec)) => vec.serialize(serializer),
628            LazyPacked::Parsed(Parsed::String(s)) => s.serialize(serializer),
629            LazyPacked::Parsed(Parsed::Number(n)) => n.serialize(serializer),
630            LazyPacked::Parsed(Parsed::Bool(b)) => b.serialize(serializer),
631            LazyPacked::Parsed(Parsed::Null) => serializer.serialize_none(),
632        }
633    }
634}
635
636#[derive(Debug, Clone, RefCast)]
637#[repr(transparent)]
638pub struct LazyObject(OwnedLazyValue);
639
640impl std::ops::Deref for LazyObject {
641    type Target = Vec<(FastStr, OwnedLazyValue)>;
642    fn deref(&self) -> &Self::Target {
643        if let LazyPacked::Parsed(Parsed::LazyObject(obj)) = &self.0 .0 {
644            obj
645        } else {
646            unreachable!("must be a lazy object");
647        }
648    }
649}
650
651impl std::ops::DerefMut for LazyObject {
652    fn deref_mut(&mut self) -> &mut Self::Target {
653        if let LazyPacked::Parsed(Parsed::LazyObject(obj)) = &mut self.0 .0 {
654            obj
655        } else {
656            unreachable!("must be a lazy object");
657        }
658    }
659}
660
661impl Default for LazyObject {
662    fn default() -> Self {
663        Self::new()
664    }
665}
666
667impl LazyObject {
668    pub fn new() -> Self {
669        Self(OwnedLazyValue(LazyPacked::Parsed(Parsed::LazyObject(
670            Vec::new(),
671        ))))
672    }
673
674    pub fn with_capacity(cap: usize) -> Self {
675        Self(OwnedLazyValue(LazyPacked::Parsed(Parsed::LazyObject(
676            Vec::with_capacity(cap),
677        ))))
678    }
679
680    pub fn append_pair(&mut self, key: FastStr, value: OwnedLazyValue) {
681        if let LazyPacked::Parsed(Parsed::LazyObject(obj)) = &mut self.0 .0 {
682            obj.push((key, value));
683        } else {
684            unreachable!("must be a lazy object");
685        }
686    }
687}
688
689impl From<Vec<(FastStr, OwnedLazyValue)>> for LazyObject {
690    fn from(v: Vec<(FastStr, OwnedLazyValue)>) -> Self {
691        Self(OwnedLazyValue(LazyPacked::Parsed(Parsed::LazyObject(v))))
692    }
693}
694
695impl From<LazyObject> for OwnedLazyValue {
696    fn from(v: LazyObject) -> Self {
697        v.0
698    }
699}
700
701#[derive(Debug, Clone, RefCast)]
702#[repr(transparent)]
703pub struct LazyArray(OwnedLazyValue);
704
705impl From<Vec<OwnedLazyValue>> for LazyArray {
706    fn from(v: Vec<OwnedLazyValue>) -> Self {
707        Self(OwnedLazyValue(LazyPacked::Parsed(Parsed::LazyArray(v))))
708    }
709}
710
711impl From<LazyArray> for OwnedLazyValue {
712    fn from(v: LazyArray) -> Self {
713        v.0
714    }
715}
716
717impl std::ops::DerefMut for LazyArray {
718    fn deref_mut(&mut self) -> &mut Self::Target {
719        if let LazyPacked::Parsed(Parsed::LazyArray(obj)) = &mut self.0 .0 {
720            obj
721        } else {
722            unreachable!("must be a lazy array");
723        }
724    }
725}
726
727impl std::ops::Deref for LazyArray {
728    type Target = Vec<OwnedLazyValue>;
729    fn deref(&self) -> &Self::Target {
730        if let LazyPacked::Parsed(Parsed::LazyArray(obj)) = &self.0 .0 {
731            obj
732        } else {
733            unreachable!("must be a lazy array");
734        }
735    }
736}
737
738impl Default for LazyArray {
739    fn default() -> Self {
740        Self::new()
741    }
742}
743
744impl LazyArray {
745    pub fn new() -> Self {
746        Self(OwnedLazyValue(LazyPacked::Parsed(Parsed::LazyArray(
747            Vec::new(),
748        ))))
749    }
750
751    pub fn with_capacity(cap: usize) -> Self {
752        Self(OwnedLazyValue(LazyPacked::Parsed(Parsed::LazyArray(
753            Vec::with_capacity(cap),
754        ))))
755    }
756}
757
758#[cfg(test)]
759mod test {
760    use crate::{get, pointer, prelude::*, to_lazyvalue, to_string, FastStr, OwnedLazyValue};
761    #[test]
762    fn test_owned_lazy_value() {
763        let mut lv: OwnedLazyValue =
764            crate::get_from_faststr(&FastStr::new(r#"{"a": "hello world"}"#), pointer![])
765                .unwrap()
766                .into();
767        dbg!(&lv);
768
769        if let Some(obj) = lv.as_object_mut() {
770            for (k, v) in obj.iter_mut() {
771                dbg!(k, v);
772            }
773
774            obj.append_pair(FastStr::new("foo"), to_lazyvalue("bar").unwrap());
775        }
776
777        dbg!(crate::to_string(&lv).unwrap());
778
779        let input = r#"{
780          "a": "hello world",
781          "a\\": "\\hello \" world",
782          "b": true,
783          "c": [0, 1, 2],
784          "d": {
785             "sonic": "rs"
786           }
787         }"#;
788        let own_a = OwnedLazyValue::from(get(input, &["a"]).unwrap());
789        let own_c = OwnedLazyValue::from(get(input, &["c"]).unwrap());
790        let own = OwnedLazyValue::from(get(input, pointer![]).unwrap());
791        // use as_xx to get the parsed value
792        assert_eq!(own_a.as_str().unwrap(), "hello world");
793        assert_eq!(own.get("a\\").as_str().unwrap(), "\\hello \" world");
794        assert_eq!(own_c.as_str(), None);
795        assert!(own_c.is_array());
796    }
797
798    #[test]
799    fn test_owned_array() {
800        let mut lv: OwnedLazyValue =
801            crate::get_from_faststr(&FastStr::new(r#"["a", "hello world"]"#), pointer![])
802                .unwrap()
803                .into();
804        dbg!(&lv);
805
806        if let Some(arr) = lv.as_array_mut() {
807            for v in arr.iter_mut() {
808                dbg!(v);
809            }
810
811            arr.push(to_lazyvalue("bar").unwrap());
812        }
813
814        dbg!(crate::to_string(&lv).unwrap());
815    }
816
817    #[test]
818    fn test_owned_value_pointer() {
819        let input = FastStr::from(String::from(
820            r#"{
821          "a": "hello world",
822          "b": true,
823          "c": [0, 1, 2],
824          "d": {
825             "sonic": "rs"
826           }
827         }"#,
828        ));
829        let root: OwnedLazyValue =
830            unsafe { crate::get_unchecked(&input, pointer![]).unwrap() }.into();
831        test_pointer(&root);
832        test_pointer(&root.clone());
833        test_pointer(&to_lazyvalue(&root).unwrap());
834
835        fn test_pointer(lv: &OwnedLazyValue) {
836            assert!(lv.pointer(pointer!["aa"]).is_none());
837            assert!(lv.get("aa").is_none());
838            assert_eq!(lv.pointer(pointer!["a"]).as_str(), Some("hello world"));
839            assert_eq!(lv.get("a").as_str(), Some("hello world"));
840            assert_eq!(lv.pointer(pointer!["b"]).as_bool(), Some(true));
841            assert_eq!(lv.get("b").as_bool(), Some(true));
842            assert_eq!(lv.pointer(pointer!["c", 1]).as_i64(), Some(1));
843            assert_eq!(lv.pointer(pointer!["c", 3]).as_i64(), None);
844        }
845    }
846
847    #[test]
848    fn test_owned_value_mut() {
849        let input = FastStr::from(String::from(
850            r#"{
851          "a": "hello world",
852          "b": true,
853          "c": [0, 1, 2],
854          "d": {
855             "sonic": "rs"
856           }
857         }"#,
858        ));
859        let mut root: OwnedLazyValue =
860            unsafe { crate::get_unchecked(&input, pointer![]).unwrap() }.into();
861        let mut root2 = root.clone();
862        let mut root3 = to_lazyvalue(&root2).unwrap();
863        test_pointer(&mut root);
864        test_pointer(&mut root2);
865        test_pointer(&mut root3);
866
867        fn test_pointer(lv: &mut OwnedLazyValue) {
868            assert!(lv.pointer_mut(pointer!["aa"]).is_none());
869            assert!(lv.get_mut("aa").is_none());
870            assert_eq!(
871                lv.pointer_mut(pointer!["a"]).unwrap().as_str(),
872                Some("hello world")
873            );
874            assert_eq!(lv.get_mut("a").unwrap().as_str(), Some("hello world"));
875            assert_eq!(lv.pointer_mut(pointer!["b"]).unwrap().as_bool(), Some(true));
876            assert_eq!(lv.get_mut("b").unwrap().as_bool(), Some(true));
877            let sub = lv.pointer_mut(pointer!["c", 1]).unwrap();
878            assert_eq!(sub.as_i64(), Some(1));
879            *sub = to_lazyvalue(&3).unwrap();
880            assert_eq!(sub.as_i64(), Some(3));
881            assert!(lv.pointer_mut(pointer!["c", 3]).is_none());
882            assert_eq!(lv.pointer_mut(pointer!["c", 1]).unwrap().as_i64(), Some(3));
883        }
884
885        assert_eq!(to_string(&root).unwrap(), to_string(&root2).unwrap());
886        assert_eq!(to_string(&root).unwrap(), to_string(&root3).unwrap());
887    }
888
889    #[test]
890    fn test_owned_from_invalid() {
891        for json in [
892            r#"", 
893            r#"{"a":"#,
894            r#"{"a":123"#,
895            r#"{"a":}"#,
896            r#"{"a": x}"#,
897            r#"{"a":1.}"#,
898            r#"{"a:1.}"#,
899            r#"{"a" 1}"#,
900            r#"{"a"[1}}"#,
901        ] {
902            crate::from_str::<OwnedLazyValue>(json).expect_err(json);
903        }
904    }
905}