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) => {
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 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 s.serialize_field(super::TOKEN, raw)?;
629 s.end()
630 }
631 LazyPacked::Parsed(Parsed::LazyObject(vec)) => {
632 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 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}