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 match self
161 .parsed
162 .compare_exchange_weak(ptr, parsed, Ordering::AcqRel, Ordering::Acquire)
163 {
164 Ok(_) => Ok(unsafe { &*parsed }),
166 Err(ptr) => {
167 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 Err(unsafe { (*parsed).clone() })
255 }
256 }
257}
258
259#[derive(Debug)]
260pub(crate) enum LazyPacked {
261 Raw(LazyRaw),
263 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 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 s.serialize_field(super::TOKEN, raw)?;
622 s.end()
623 }
624 LazyPacked::Parsed(Parsed::LazyObject(vec)) => {
625 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 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}