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) => {
504                if raw.get_type() == JsonType::Array {
505                    raw.load().ok()?
506                } else {
507                    return None;
508                }
509            }
510            LazyPacked::Parsed(parsed) => parsed,
511            _ => return None,
512        };
513
514        if let Parsed::LazyArray(_) = parsed {
515            Some(LazyArray::ref_cast(self))
516        } else {
517            None
518        }
519    }
520
521    #[inline]
522    fn as_object(&self) -> Option<&Self::ObjectType> {
523        let parsed = match &self.0 {
524            LazyPacked::Raw(raw) => {
525                if raw.get_type() == JsonType::Object {
526                    raw.load().ok()?
527                } else {
528                    return None;
529                }
530            }
531            LazyPacked::Parsed(parsed) => parsed,
532            _ => return None,
533        };
534
535        if let Parsed::LazyObject(_) = parsed {
536            Some(LazyObject::ref_cast(self))
537        } else {
538            None
539        }
540    }
541}
542
543impl OwnedLazyValue {
544    pub fn take(&mut self) -> Self {
545        std::mem::take(self)
546    }
547
548    pub(crate) fn new(raw: JsonSlice, status: HasEsc) -> Self {
549        let raw = match raw {
550            JsonSlice::Raw(r) => FastStr::new(unsafe { from_utf8_unchecked(r) }),
551            JsonSlice::FastStr(f) => f.clone(),
552        };
553
554        if status == HasEsc::None {
555            Self(LazyPacked::NonEscStrRaw(raw))
556        } else {
557            Self(LazyPacked::Raw(LazyRaw {
558                raw,
559                parsed: AtomicPtr::new(std::ptr::null_mut()),
560            }))
561        }
562    }
563
564    fn get_mut_from_raw<I: Index>(&mut self, index: I) -> Option<&mut Self> {
565        let raw = if let LazyPacked::Raw(raw) = &mut self.0 {
566            raw
567        } else {
568            return None;
569        };
570
571        match raw.get_type() {
572            JsonType::Array if index.as_index().is_some() => {
573                let parsed = raw.parse().ok()?;
574                *self = Self(LazyPacked::Parsed(parsed));
575            }
576            JsonType::Object if index.as_key().is_some() => {
577                let parsed = raw.parse().ok()?;
578                *self = Self(LazyPacked::Parsed(parsed));
579            }
580            _ => return None,
581        }
582
583        if let LazyPacked::Parsed(parsed) = &mut self.0 {
584            parsed.get_mut(index)
585        } else {
586            None
587        }
588    }
589}
590
591impl<'de> From<LazyValue<'de>> for OwnedLazyValue {
592    fn from(lv: LazyValue<'de>) -> Self {
593        let raw = unsafe { lv.raw.as_faststr() };
594        if lv.inner.no_escaped() && raw.as_bytes()[0] == b'"' {
595            return Self(LazyPacked::NonEscStrRaw(raw));
596        }
597
598        Self(LazyPacked::Raw(LazyRaw {
599            raw,
600            parsed: AtomicPtr::new(std::ptr::null_mut()),
601        }))
602    }
603}
604
605impl Display for OwnedLazyValue {
606    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
607        write!(f, "{:?}", crate::to_string(self))
608    }
609}
610
611impl serde::ser::Serialize for OwnedLazyValue {
612    fn serialize<S>(&self, serializer: S) -> std::result::Result<S::Ok, S::Error>
613    where
614        S: serde::Serializer,
615    {
616        match &self.0 {
617            LazyPacked::Raw(raw) => {
618                let raw = 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::NonEscStrRaw(raw) => {
625                let raw = raw.as_str();
626                let mut s = serializer.serialize_struct(super::TOKEN, 1)?;
627                // will directly write raw in `LazyValueStrEmitter::seriazlie_str`
628                s.serialize_field(super::TOKEN, raw)?;
629                s.end()
630            }
631            LazyPacked::Parsed(Parsed::LazyObject(vec)) => {
632                // if expected to be sort-keys, should use `sonic_rs::Value`
633                let mut map = serializer.serialize_map(Some(vec.len()))?;
634                for (k, v) in vec {
635                    map.serialize_entry(k, v)?;
636                }
637                map.end()
638            }
639            LazyPacked::Parsed(Parsed::LazyArray(vec)) => vec.serialize(serializer),
640            LazyPacked::Parsed(Parsed::String(s)) => s.serialize(serializer),
641            LazyPacked::Parsed(Parsed::Number(n)) => n.serialize(serializer),
642            LazyPacked::Parsed(Parsed::Bool(b)) => b.serialize(serializer),
643            LazyPacked::Parsed(Parsed::Null) => serializer.serialize_none(),
644        }
645    }
646}
647
648#[derive(Debug, Clone, RefCast)]
649#[repr(transparent)]
650pub struct LazyObject(OwnedLazyValue);
651
652impl std::ops::Deref for LazyObject {
653    type Target = Vec<(FastStr, OwnedLazyValue)>;
654    fn deref(&self) -> &Self::Target {
655        if let LazyPacked::Parsed(Parsed::LazyObject(obj)) = &self.0 .0 {
656            obj
657        } else {
658            unreachable!("must be a lazy object");
659        }
660    }
661}
662
663impl std::ops::DerefMut for LazyObject {
664    fn deref_mut(&mut self) -> &mut Self::Target {
665        if let LazyPacked::Parsed(Parsed::LazyObject(obj)) = &mut self.0 .0 {
666            obj
667        } else {
668            unreachable!("must be a lazy object");
669        }
670    }
671}
672
673impl Default for LazyObject {
674    fn default() -> Self {
675        Self::new()
676    }
677}
678
679impl LazyObject {
680    pub fn new() -> Self {
681        Self(OwnedLazyValue(LazyPacked::Parsed(Parsed::LazyObject(
682            Vec::new(),
683        ))))
684    }
685
686    pub fn with_capacity(cap: usize) -> Self {
687        Self(OwnedLazyValue(LazyPacked::Parsed(Parsed::LazyObject(
688            Vec::with_capacity(cap),
689        ))))
690    }
691
692    pub fn append_pair(&mut self, key: FastStr, value: OwnedLazyValue) {
693        if let LazyPacked::Parsed(Parsed::LazyObject(obj)) = &mut self.0 .0 {
694            obj.push((key, value));
695        } else {
696            unreachable!("must be a lazy object");
697        }
698    }
699}
700
701impl From<Vec<(FastStr, OwnedLazyValue)>> for LazyObject {
702    fn from(v: Vec<(FastStr, OwnedLazyValue)>) -> Self {
703        Self(OwnedLazyValue(LazyPacked::Parsed(Parsed::LazyObject(v))))
704    }
705}
706
707impl From<LazyObject> for OwnedLazyValue {
708    fn from(v: LazyObject) -> Self {
709        v.0
710    }
711}
712
713#[derive(Debug, Clone, RefCast)]
714#[repr(transparent)]
715pub struct LazyArray(OwnedLazyValue);
716
717impl From<Vec<OwnedLazyValue>> for LazyArray {
718    fn from(v: Vec<OwnedLazyValue>) -> Self {
719        Self(OwnedLazyValue(LazyPacked::Parsed(Parsed::LazyArray(v))))
720    }
721}
722
723impl From<LazyArray> for OwnedLazyValue {
724    fn from(v: LazyArray) -> Self {
725        v.0
726    }
727}
728
729impl std::ops::DerefMut for LazyArray {
730    fn deref_mut(&mut self) -> &mut Self::Target {
731        if let LazyPacked::Parsed(Parsed::LazyArray(obj)) = &mut self.0 .0 {
732            obj
733        } else {
734            unreachable!("must be a lazy array");
735        }
736    }
737}
738
739impl std::ops::Deref for LazyArray {
740    type Target = Vec<OwnedLazyValue>;
741    fn deref(&self) -> &Self::Target {
742        if let LazyPacked::Parsed(Parsed::LazyArray(obj)) = &self.0 .0 {
743            obj
744        } else {
745            unreachable!("must be a lazy array");
746        }
747    }
748}
749
750impl Default for LazyArray {
751    fn default() -> Self {
752        Self::new()
753    }
754}
755
756impl LazyArray {
757    pub fn new() -> Self {
758        Self(OwnedLazyValue(LazyPacked::Parsed(Parsed::LazyArray(
759            Vec::new(),
760        ))))
761    }
762
763    pub fn with_capacity(cap: usize) -> Self {
764        Self(OwnedLazyValue(LazyPacked::Parsed(Parsed::LazyArray(
765            Vec::with_capacity(cap),
766        ))))
767    }
768}
769
770#[cfg(test)]
771mod test {
772    use crate::{get, pointer, prelude::*, to_lazyvalue, to_string, FastStr, OwnedLazyValue};
773    #[test]
774    fn test_owned_lazy_value() {
775        let mut lv: OwnedLazyValue =
776            crate::get_from_faststr(&FastStr::new(r#"{"a": "hello world"}"#), pointer![])
777                .unwrap()
778                .into();
779        dbg!(&lv);
780
781        if let Some(obj) = lv.as_object_mut() {
782            for (k, v) in obj.iter_mut() {
783                dbg!(k, v);
784            }
785
786            obj.append_pair(FastStr::new("foo"), to_lazyvalue("bar").unwrap());
787        }
788
789        dbg!(crate::to_string(&lv).unwrap());
790
791        let input = r#"{
792          "a": "hello world",
793          "a\\": "\\hello \" world",
794          "b": true,
795          "c": [0, 1, 2],
796          "d": {
797             "sonic": "rs"
798           }
799         }"#;
800        let own_a = OwnedLazyValue::from(get(input, &["a"]).unwrap());
801        let own_c = OwnedLazyValue::from(get(input, &["c"]).unwrap());
802        let own = OwnedLazyValue::from(get(input, pointer![]).unwrap());
803        // use as_xx to get the parsed value
804        assert_eq!(own_a.as_str().unwrap(), "hello world");
805        assert_eq!(own.get("a\\").as_str().unwrap(), "\\hello \" world");
806        assert_eq!(own_c.as_str(), None);
807        assert!(own_c.is_array());
808    }
809
810    #[test]
811    fn test_owned_array() {
812        let mut lv: OwnedLazyValue =
813            crate::get_from_faststr(&FastStr::new(r#"["a", "hello world"]"#), pointer![])
814                .unwrap()
815                .into();
816        dbg!(&lv);
817
818        if let Some(arr) = lv.as_array_mut() {
819            for v in arr.iter_mut() {
820                dbg!(v);
821            }
822
823            arr.push(to_lazyvalue("bar").unwrap());
824        }
825
826        dbg!(crate::to_string(&lv).unwrap());
827    }
828
829    #[test]
830    fn test_owned_value_pointer() {
831        let input = FastStr::from(String::from(
832            r#"{
833          "a": "hello world",
834          "b": true,
835          "c": [0, 1, 2],
836          "d": {
837             "sonic": "rs"
838           }
839         }"#,
840        ));
841        let root: OwnedLazyValue =
842            unsafe { crate::get_unchecked(&input, pointer![]).unwrap() }.into();
843        test_pointer(&root);
844        test_pointer(&root.clone());
845        test_pointer(&to_lazyvalue(&root).unwrap());
846
847        fn test_pointer(lv: &OwnedLazyValue) {
848            assert!(lv.pointer(pointer!["aa"]).is_none());
849            assert!(lv.get("aa").is_none());
850            assert_eq!(lv.pointer(pointer!["a"]).as_str(), Some("hello world"));
851            assert_eq!(lv.get("a").as_str(), Some("hello world"));
852            assert_eq!(lv.pointer(pointer!["b"]).as_bool(), Some(true));
853            assert_eq!(lv.get("b").as_bool(), Some(true));
854            assert_eq!(lv.pointer(pointer!["c", 1]).as_i64(), Some(1));
855            assert_eq!(lv.pointer(pointer!["c", 3]).as_i64(), None);
856        }
857    }
858
859    #[test]
860    fn test_owned_value_mut() {
861        let input = FastStr::from(String::from(
862            r#"{
863          "a": "hello world",
864          "b": true,
865          "c": [0, 1, 2],
866          "d": {
867             "sonic": "rs"
868           }
869         }"#,
870        ));
871        let mut root: OwnedLazyValue =
872            unsafe { crate::get_unchecked(&input, pointer![]).unwrap() }.into();
873        let mut root2 = root.clone();
874        let mut root3 = to_lazyvalue(&root2).unwrap();
875        test_pointer(&mut root);
876        test_pointer(&mut root2);
877        test_pointer(&mut root3);
878
879        fn test_pointer(lv: &mut OwnedLazyValue) {
880            assert!(lv.pointer_mut(pointer!["aa"]).is_none());
881            assert!(lv.get_mut("aa").is_none());
882            assert_eq!(
883                lv.pointer_mut(pointer!["a"]).unwrap().as_str(),
884                Some("hello world")
885            );
886            assert_eq!(lv.get_mut("a").unwrap().as_str(), Some("hello world"));
887            assert_eq!(lv.pointer_mut(pointer!["b"]).unwrap().as_bool(), Some(true));
888            assert_eq!(lv.get_mut("b").unwrap().as_bool(), Some(true));
889            let sub = lv.pointer_mut(pointer!["c", 1]).unwrap();
890            assert_eq!(sub.as_i64(), Some(1));
891            *sub = to_lazyvalue(&3).unwrap();
892            assert_eq!(sub.as_i64(), Some(3));
893            assert!(lv.pointer_mut(pointer!["c", 3]).is_none());
894            assert_eq!(lv.pointer_mut(pointer!["c", 1]).unwrap().as_i64(), Some(3));
895        }
896
897        assert_eq!(to_string(&root).unwrap(), to_string(&root2).unwrap());
898        assert_eq!(to_string(&root).unwrap(), to_string(&root3).unwrap());
899    }
900
901    #[test]
902    fn test_owned_from_invalid() {
903        for json in [
904            r#"", 
905            r#"{"a":"#,
906            r#"{"a":123"#,
907            r#"{"a":}"#,
908            r#"{"a": x}"#,
909            r#"{"a":1.}"#,
910            r#"{"a:1.}"#,
911            r#"{"a" 1}"#,
912            r#"{"a"[1}}"#,
913        ] {
914            crate::from_str::<OwnedLazyValue>(json).expect_err(json);
915        }
916    }
917}