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