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#[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 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 Ok(_) => return Ok(unsafe { &*parsed }),
169 Err(ptr) => {
170 if ptr.is_null() {
171 continue;
172 }
173 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 Err(unsafe { (*parsed).clone() })
262 }
263 }
264}
265
266#[derive(Debug)]
267pub(crate) enum LazyPacked {
268 Raw(LazyRaw),
270 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 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 s.serialize_field(super::TOKEN, raw)?;
617 s.end()
618 }
619 LazyPacked::Parsed(Parsed::LazyObject(vec)) => {
620 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 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}