1use std::cell::{Cell, OnceCell, Ref, RefCell, RefMut};
10use std::cmp::Ordering;
11use std::collections::HashSet;
12use std::fmt::Write as _;
13use std::rc::Rc;
14use std::sync::Arc;
15
16use indexmap::IndexMap;
17use serde_json::Value as JsonValue;
18
19use crate::ast::{LambdaDef, Span, TransformDef};
20use crate::error::{Error, Result};
21use crate::eval::Env;
22use crate::functions::Native;
23use crate::host::HostFunction;
24use crate::output::Builder;
25use crate::regex::Regex;
26
27pub(crate) type Map<'a> = IndexMap<Rc<str>, Value<'a>, foldhash::fast::RandomState>;
30
31#[derive(Default)]
34pub(crate) struct Keys(HashSet<Rc<str>, foldhash::fast::RandomState>);
35
36impl Keys {
37 const CAPACITY: usize = 1024;
41
42 pub(crate) fn get(&mut self, key: &str) -> Rc<str> {
43 if let Some(shared) = self.0.get(key) {
44 return shared.clone();
45 }
46 let key: Rc<str> = key.into();
47 if self.0.len() < Self::CAPACITY {
48 self.0.insert(key.clone());
49 }
50 key
51 }
52}
53
54#[derive(Default)]
57pub(crate) struct Shared {
58 keys: RefCell<Keys>,
59 failed: Cell<bool>,
60 failure: RefCell<Option<String>>,
61}
62
63impl Shared {
64 pub(crate) fn new() -> Rc<Shared> {
65 Rc::default()
66 }
67
68 #[inline]
70 pub(crate) fn failed(&self) -> bool {
71 self.failed.get()
72 }
73
74 #[cold]
76 #[inline(never)]
77 pub(crate) fn failure(&self) -> Error {
78 let failure = self.failure.borrow();
79 Error::new("U1004").with("message", failure.as_deref().unwrap_or_default())
80 }
81
82 fn fail(&self, message: String) {
83 self.failed.set(true);
84 self.failure.borrow_mut().get_or_insert(message);
85 }
86}
87
88struct Pending<'a> {
91 origin: Origin<'a>,
92 shared: Rc<Shared>,
93}
94
95enum Origin<'a> {
96 Json(&'a JsonValue),
97 Source(Rc<dyn Sources<'a> + 'a>),
101}
102
103struct Only<S>(S);
105
106impl<'a, S: Source<'a>> Sources<'a> for Only<S> {
107 fn read(&self, _: u32, sink: &mut Sink<'_, 'a>) -> std::result::Result<(), String> {
108 self.0.read(sink)
109 }
110
111 fn read_field(
112 &self,
113 _: u32,
114 key: &str,
115 sink: &mut Sink<'_, 'a>,
116 ) -> std::result::Result<bool, String> {
117 self.0.read_field(key, sink)
118 }
119}
120
121impl<'a> Pending<'a> {
122 fn json(&self) -> Option<&'a JsonValue> {
124 match self.origin {
125 Origin::Json(json) => Some(json),
126 Origin::Source(_) => None,
127 }
128 }
129
130 fn read_source(&self, sources: &dyn Sources<'a>, member: u32, level: Level<'_, 'a>) {
134 let mut sink = Sink {
135 level,
136 shared: &self.shared,
137 key: None,
138 };
139 if let Err(message) = sources.read(member, &mut sink) {
140 self.shared.fail(message);
141 match sink.level {
142 Level::Items(items) => items.clear(),
143 Level::Fields(map) => map.clear(),
144 Level::Field(_) => {}
145 }
146 }
147 }
148
149 fn read_source_field(
153 &self,
154 sources: &dyn Sources<'a>,
155 member: u32,
156 key: &str,
157 ) -> Option<Value<'a>> {
158 let mut value = Value::Undefined;
159 let mut sink = Sink {
160 level: Level::Field(&mut value),
161 shared: &self.shared,
162 key: None,
163 };
164 match sources.read_field(member, key, &mut sink) {
165 Ok(true) => Some(value),
166 Ok(false) => None,
167 Err(message) => {
168 self.shared.fail(message);
169 Some(Value::Undefined)
170 }
171 }
172 }
173}
174
175#[derive(Clone, Default)]
177pub(crate) enum Value<'a> {
178 #[default]
179 Undefined,
180 Null,
181 Bool(bool),
182 Number(f64),
183 String(Rc<str>),
184 Array(Rc<Array<'a>>),
185 Object(Rc<Object<'a>>),
186 Function(Rc<Function<'a>>),
187}
188
189pub(crate) const SEQUENCE: u8 = 1;
190pub(crate) const KEEP_SINGLETON: u8 = 2;
191pub(crate) const OUTER_WRAPPER: u8 = 4;
192pub(crate) const CONS: u8 = 8;
193pub(crate) const TUPLE_STREAM: u8 = 16;
194
195pub(crate) struct Array<'a> {
197 items: Vec<Value<'a>>,
200 flags: Cell<u8>,
201 lazy: Option<Box<LazyItems<'a>>>,
204}
205
206struct LazyItems<'a> {
207 pending: Pending<'a>,
208 member: u32,
210 items: OnceCell<Vec<Value<'a>>>,
211}
212
213impl<'a> LazyItems<'a> {
214 #[inline(never)]
216 fn read(&self) -> &Vec<Value<'a>> {
217 let pending = &self.pending;
218 self.items.get_or_init(|| match &pending.origin {
219 Origin::Json(JsonValue::Array(items)) => items
220 .iter()
221 .map(|v| Value::lazy(v, &pending.shared))
222 .collect(),
223 Origin::Json(_) => Vec::new(),
224 Origin::Source(sources) => {
225 let mut items = Vec::new();
226 pending.read_source(&**sources, self.member, Level::Items(&mut items));
227 items
228 }
229 })
230 }
231}
232
233impl<'a> Array<'a> {
234 #[inline]
236 pub fn items(&self) -> &Vec<Value<'a>> {
237 match &self.lazy {
238 None => &self.items,
239 Some(lazy) => lazy.read(),
240 }
241 }
242
243 fn unread(&self) -> Option<&'a JsonValue> {
245 match &self.lazy {
246 Some(lazy) if lazy.items.get().is_none() => lazy.pending.json(),
247 _ => None,
248 }
249 }
250
251 pub fn is_unread(&self) -> bool {
254 self.lazy
255 .as_ref()
256 .is_some_and(|lazy| lazy.items.get().is_none())
257 }
258
259 pub fn has(&self, flag: u8) -> bool {
260 self.flags.get() & flag != 0
261 }
262
263 pub fn set(&self, flag: u8) {
264 self.flags.set(self.flags.get() | flag);
265 }
266
267 pub fn is_sequence(&self) -> bool {
268 self.has(SEQUENCE)
269 }
270
271 pub fn is_tuple_stream(&self) -> bool {
272 self.has(TUPLE_STREAM)
273 }
274
275 pub fn len(&self) -> usize {
276 match self.unread() {
277 Some(JsonValue::Array(items)) => items.len(),
278 _ => self.items().len(),
279 }
280 }
281}
282
283pub(crate) struct Object<'a> {
286 map: RefCell<Map<'a>>,
288 pending: Option<Pending<'a>>,
291 read: Cell<Read>,
292 member: u32,
294}
295
296#[derive(Clone, Copy, PartialEq, Eq)]
298enum Read {
299 Nothing,
300 Fields,
303 Whole,
304}
305
306impl<'a> Object<'a> {
307 #[inline]
308 fn cell(&self) -> &RefCell<Map<'a>> {
309 if let Some(pending) = &self.pending
310 && self.read.get() != Read::Whole
311 {
312 self.read(pending);
313 }
314 &self.map
315 }
316
317 #[cold]
321 #[inline(never)]
322 fn read(&self, pending: &Pending<'a>) {
323 let before = self.read.replace(Read::Whole);
324 let Ok(mut map) = self.map.try_borrow_mut() else {
325 return;
326 };
327 let mut alone = std::mem::take(&mut *map);
328 match &pending.origin {
329 Origin::Json(JsonValue::Object(fields)) => {
330 *map = Map::with_capacity_and_hasher(fields.len(), Default::default());
331 let mut keys = pending.shared.keys.borrow_mut();
332 for (k, v) in fields {
333 let value = match alone.is_empty() {
334 true => None,
335 false => alone.swap_remove(k.as_str()),
336 };
337 let value = value.unwrap_or_else(|| Value::lazy(v, &pending.shared));
338 map.insert(keys.get(k), value);
339 }
340 }
341 Origin::Json(_) => {}
342 Origin::Source(sources) => {
343 pending.read_source(&**sources, self.member, Level::Fields(&mut map))
344 }
345 }
346 if before == Read::Fields {
347 for (key, value) in alone {
348 if let Some(slot) = map.get_mut(&key) {
349 *slot = value;
350 }
351 }
352 }
353 }
354
355 #[inline]
358 pub fn get(&self, key: &str) -> Value<'a> {
359 match &self.pending {
360 Some(pending) if self.read.get() != Read::Whole => self.read_field(pending, key),
361 _ => self.map.borrow().get(key).cloned().unwrap_or_default(),
362 }
363 }
364
365 #[cold]
366 #[inline(never)]
367 fn read_field(&self, pending: &Pending<'a>, key: &str) -> Value<'a> {
368 if self.read.get() == Read::Fields
369 && let Some(value) = self.map.borrow().get(key)
370 {
371 return value.clone();
372 }
373 let value = match &pending.origin {
374 Origin::Json(JsonValue::Object(fields)) => {
375 let json = if fields.len() <= 16 {
378 fields.iter().find(|(k, _)| *k == key).map(|(_, v)| v)
379 } else {
380 fields.get(key)
381 };
382 let Some(json) = json else {
383 return Value::Undefined;
384 };
385 Value::lazy(json, &pending.shared)
386 }
387 Origin::Json(_) => return Value::Undefined,
388 Origin::Source(sources) => {
389 match pending.read_source_field(&**sources, self.member, key) {
390 Some(Value::Undefined) => return Value::Undefined,
391 Some(value) => value,
392 None => return self.borrow().get(key).cloned().unwrap_or_default(),
393 }
394 }
395 };
396 if let Value::Array(_) | Value::Object(_) = value {
400 let key = pending.shared.keys.borrow_mut().get(key);
401 self.map.borrow_mut().insert(key, value.clone());
402 self.read.set(Read::Fields);
403 }
404 value
405 }
406
407 #[inline]
409 pub fn borrow(&self) -> Ref<'_, Map<'a>> {
410 self.cell().borrow()
411 }
412
413 #[inline]
415 pub fn borrow_mut(&self) -> RefMut<'_, Map<'a>> {
416 self.cell().borrow_mut()
417 }
418
419 fn unread(&self) -> Option<&'a JsonValue> {
421 match &self.pending {
422 Some(p) if self.read.get() == Read::Nothing => p.json(),
423 _ => None,
424 }
425 }
426
427 pub fn is_unread(&self) -> bool {
430 self.pending.is_some() && self.read.get() == Read::Nothing
431 }
432}
433
434impl Drop for Array<'_> {
440 fn drop(&mut self) {
441 let lazy = self.lazy.as_mut().and_then(|lazy| lazy.items.take());
442 let read = lazy.as_deref().unwrap_or_default();
443 if !self.items.iter().chain(read).any(owned) {
444 return;
445 }
446 let items = std::mem::take(&mut self.items);
447 nested_drop(|deep| {
448 if deep {
449 release(items.into_iter().chain(lazy.into_iter().flatten()));
450 } else {
451 drop((items, lazy));
452 }
453 });
454 }
455}
456
457impl Drop for Object<'_> {
458 fn drop(&mut self) {
459 let map = self.map.get_mut();
460 if !map.values().any(owned) {
461 return;
462 }
463 let map = std::mem::replace(map, Map::with_hasher(map.hasher().clone()));
466 nested_drop(|deep| {
467 if deep {
468 release(map.into_values());
469 } else {
470 drop(map);
471 }
472 });
473 }
474}
475
476fn owned(v: &Value<'_>) -> bool {
478 match v {
479 Value::Array(a) => Rc::strong_count(a) == 1,
480 Value::Object(o) => Rc::strong_count(o) == 1,
481 _ => false,
482 }
483}
484
485const DROP_DEPTH: usize = 100;
487
488thread_local! {
489 static DROPS: Cell<usize> = const { Cell::new(0) };
490}
491
492fn nested_drop(drop: impl FnOnce(bool)) {
495 DROPS.with(|drops| {
496 let depth = drops.get();
497 drops.set(depth + 1);
498 drop(depth >= DROP_DEPTH);
499 drops.set(depth);
500 });
501}
502
503pub(crate) fn for_each_leaf<'v, 'a, E>(
506 items: &'v [Value<'a>],
507 mut f: impl FnMut(&'v Value<'a>) -> std::result::Result<(), E>,
508) -> std::result::Result<(), E> {
509 let mut outer = Vec::new();
510 let mut iter = items.iter();
511 loop {
512 match iter.next() {
513 Some(Value::Array(a)) => outer.push(std::mem::replace(&mut iter, a.items().iter())),
514 Some(leaf) => f(leaf)?,
515 None => match outer.pop() {
516 Some(rest) => iter = rest,
517 None => return Ok(()),
518 },
519 }
520 }
521}
522
523fn release<'a>(values: impl IntoIterator<Item = Value<'a>>) {
526 let mut pending: Vec<Value<'a>> = values.into_iter().filter(owned).collect();
527 while let Some(value) = pending.pop() {
528 match value {
529 Value::Array(a) => {
530 if let Some(mut a) = Rc::into_inner(a) {
531 pending.extend(std::mem::take(&mut a.items).into_iter().filter(owned));
532 if let Some(items) = a.lazy.as_mut().and_then(|lazy| lazy.items.take()) {
533 pending.extend(items.into_iter().filter(owned));
534 }
535 }
536 }
537 Value::Object(o) => {
538 if let Some(mut o) = Rc::into_inner(o) {
539 let fields = std::mem::take(o.map.get_mut()).into_values();
540 pending.extend(fields.filter(owned));
541 }
542 }
543 _ => {}
544 }
545 }
546}
547
548pub(crate) enum Function<'a> {
550 Lambda(Lambda<'a>),
552 Native(&'static Native),
554 Host(HostFunction),
556 Partial {
559 target: Rc<Function<'a>>,
560 args: Vec<Option<Value<'a>>>,
561 },
562 Transform {
564 def: Arc<TransformDef>,
565 env: Env<'a>,
566 span: Span,
567 position: usize,
568 },
569 Regex(Rc<Regex>),
571 RegexNext {
573 re: Rc<Regex>,
574 text: Rc<str>,
575 last: usize,
576 },
577}
578
579pub(crate) struct Lambda<'a> {
580 pub def: Arc<LambdaDef>,
581 pub params: Option<Rc<[String]>>,
583 pub validate: bool,
585 pub input: Value<'a>,
586 pub env: Env<'a>,
587}
588
589impl<'a> Function<'a> {
590 pub fn arity(&self) -> usize {
592 match self {
593 Function::Lambda(l) => l.params().len(),
594 Function::Native(n) => n.arity,
595 Function::Host(h) => h.arity(),
596 Function::Partial { args, .. } => args.iter().filter(|a| a.is_none()).count(),
597 Function::Transform { .. } => 1,
598 Function::Regex(_) => 2,
599 Function::RegexNext { .. } => 0,
600 }
601 }
602
603 pub fn is_thunk(&self) -> bool {
604 matches!(self, Function::Lambda(l) if l.def.thunk)
605 }
606}
607
608impl<'a> Value<'a> {
609 pub fn string(s: impl Into<Rc<str>>) -> Value<'a> {
610 Value::String(s.into())
611 }
612
613 pub fn array(items: Vec<Value<'a>>, flags: u8) -> Value<'a> {
614 Value::Array(Rc::new(Array {
615 items,
616 flags: Cell::new(flags),
617 lazy: None,
618 }))
619 }
620
621 pub fn sequence(items: Vec<Value<'a>>) -> Value<'a> {
623 Value::array(items, SEQUENCE)
624 }
625
626 pub fn object(map: Map<'a>) -> Value<'a> {
627 Value::Object(Rc::new(Object {
628 map: RefCell::new(map),
629 pending: None,
630 read: Cell::new(Read::Whole),
631 member: 0,
632 }))
633 }
634
635 pub fn function(f: Function<'a>) -> Value<'a> {
636 Value::Function(Rc::new(f))
637 }
638
639 pub fn is_undefined(&self) -> bool {
640 matches!(self, Value::Undefined)
641 }
642
643 pub fn is_array(&self) -> bool {
644 matches!(self, Value::Array(_))
645 }
646
647 pub fn is_function(&self) -> bool {
648 matches!(self, Value::Function(_))
649 }
650
651 pub fn as_array(&self) -> Option<&Rc<Array<'a>>> {
652 match self {
653 Value::Array(a) => Some(a),
654 _ => None,
655 }
656 }
657
658 pub fn has_flag(&self, flag: u8) -> bool {
660 self.as_array().is_some_and(|a| a.has(flag))
661 }
662
663 pub fn items_or_self(&self) -> Vec<Value<'a>> {
666 match self {
667 Value::Array(a) => a.items().clone(),
668 other => vec![other.clone()],
669 }
670 }
671
672 pub fn is_numeric(&self) -> Result<bool> {
674 match self {
675 Value::Number(n) if n.is_nan() => Ok(false),
676 Value::Number(n) if n.is_infinite() => {
677 Err(Error::new("D1001").with("value", json_number(*n)))
678 }
679 Value::Number(_) => Ok(true),
680 _ => Ok(false),
681 }
682 }
683
684 pub fn as_number(&self) -> Option<f64> {
685 match self {
686 Value::Number(n) => Some(*n),
687 _ => None,
688 }
689 }
690
691 pub fn as_str(&self) -> Option<&str> {
692 match self {
693 Value::String(s) => Some(s),
694 _ => None,
695 }
696 }
697
698 pub fn signature_symbol(&self) -> char {
700 match self {
701 Value::Undefined => 'm',
702 Value::Null => 'l',
703 Value::Bool(_) => 'b',
704 Value::Number(_) => 'n',
705 Value::String(_) => 's',
706 Value::Array(_) => 'a',
707 Value::Object(_) => 'o',
708 Value::Function(_) => 'f',
709 }
710 }
711
712 pub fn is_array_of_numbers(&self) -> Result<bool> {
714 match self {
715 Value::Array(a) => {
716 for item in a.items() {
717 if !item.is_numeric()? {
718 return Ok(false);
719 }
720 }
721 Ok(true)
722 }
723 _ => Ok(false),
724 }
725 }
726
727 pub fn is_array_of_strings(&self) -> bool {
729 match self {
730 Value::Array(a) => a.items().iter().all(|i| matches!(i, Value::String(_))),
731 _ => false,
732 }
733 }
734
735 pub fn strict_eq(&self, other: &Value<'a>) -> bool {
737 match (self, other) {
738 (Value::Undefined, Value::Undefined) | (Value::Null, Value::Null) => true,
739 (Value::Bool(a), Value::Bool(b)) => a == b,
740 (Value::Number(a), Value::Number(b)) => a == b,
741 (Value::String(a), Value::String(b)) => a == b,
742 (Value::Array(a), Value::Array(b)) => Rc::ptr_eq(a, b),
743 (Value::Object(a), Value::Object(b)) => Rc::ptr_eq(a, b),
744 (Value::Function(a), Value::Function(b)) => Rc::ptr_eq(a, b),
745 _ => false,
746 }
747 }
748
749 pub fn deep_eq(&self, other: &Value<'a>) -> Result<bool> {
752 self.deep_eq_at(other, 0)
753 }
754
755 fn deep_eq_at(&self, other: &Value<'a>, depth: usize) -> Result<bool> {
757 let nested = |x: &Value<'a>, y: &Value<'a>| nest(depth + 1, || x.deep_eq_at(y, depth + 1));
758 match (self, other) {
759 (Value::Array(_), Value::Array(_)) | (Value::Object(_), Value::Object(_))
760 if depth >= MAX_NESTING =>
761 {
762 Err(too_deep())
763 }
764 (Value::Array(a), Value::Array(b)) => {
765 if Rc::ptr_eq(a, b) {
766 return Ok(true);
767 }
768 if a.items().len() != b.items().len() {
769 return Ok(false);
770 }
771 for (x, y) in a.items().iter().zip(b.items()) {
772 if !nested(x, y)? {
773 return Ok(false);
774 }
775 }
776 Ok(true)
777 }
778 (Value::Object(a), Value::Object(b)) => {
779 if Rc::ptr_eq(a, b) {
780 return Ok(true);
781 }
782 let (a, b) = (a.borrow(), b.borrow());
783 if a.len() != b.len() {
784 return Ok(false);
785 }
786 for (k, v) in a.iter() {
787 match b.get(k) {
788 Some(w) if nested(v, w)? => {}
789 _ => return Ok(false),
790 }
791 }
792 Ok(true)
793 }
794 _ => Ok(self.strict_eq(other)),
795 }
796 }
797
798 pub fn from_json(json: &JsonValue) -> Value<'a> {
800 Value::from_json_with(json, &mut Keys::default(), 0)
801 }
802
803 fn from_json_with(json: &JsonValue, keys: &mut Keys, depth: usize) -> Value<'a> {
805 match json {
806 JsonValue::Null => Value::Null,
807 JsonValue::Bool(b) => Value::Bool(*b),
808 JsonValue::Number(n) => Value::Number(n.as_f64().unwrap_or(f64::NAN)),
809 JsonValue::String(s) => Value::string(s.as_str()),
810 JsonValue::Array(items) => Value::array(
811 items
812 .iter()
813 .map(|v| nest(depth + 1, || Value::from_json_with(v, keys, depth + 1)))
814 .collect(),
815 0,
816 ),
817 JsonValue::Object(map) => {
818 let mut out = Map::with_capacity_and_hasher(map.len(), Default::default());
819 for (k, v) in map {
820 let v = nest(depth + 1, || Value::from_json_with(v, keys, depth + 1));
821 out.insert(keys.get(k), v);
822 }
823 Value::object(out)
824 }
825 }
826 }
827
828 pub fn lazy(json: &'a JsonValue, shared: &Rc<Shared>) -> Value<'a> {
832 let pending = || Pending {
833 origin: Origin::Json(json),
834 shared: shared.clone(),
835 };
836 match json {
837 JsonValue::Array(items) if !items.is_empty() => Value::lazy_array(pending(), 0),
838 JsonValue::Object(fields) if !fields.is_empty() => Value::lazy_object(pending(), 0),
839 JsonValue::Null => Value::Null,
840 JsonValue::Bool(b) => Value::Bool(*b),
841 JsonValue::Number(n) => Value::Number(n.as_f64().unwrap_or(f64::NAN)),
842 JsonValue::String(s) => Value::string(s.as_str()),
843 JsonValue::Array(_) => Value::array(Vec::new(), 0),
844 JsonValue::Object(_) => Value::object(Map::default()),
845 }
846 }
847
848 fn lazy_array(pending: Pending<'a>, member: u32) -> Value<'a> {
849 Value::Array(Rc::new(Array {
850 items: Vec::new(),
851 flags: Cell::new(0),
852 lazy: Some(Box::new(LazyItems {
853 pending,
854 member,
855 items: OnceCell::new(),
856 })),
857 }))
858 }
859
860 fn lazy_object(pending: Pending<'a>, member: u32) -> Value<'a> {
861 Value::Object(Rc::new(Object {
862 map: RefCell::new(Map::default()),
863 pending: Some(pending),
864 read: Cell::new(Read::Nothing),
865 member,
866 }))
867 }
868
869 pub(crate) fn from_source(source: &dyn Source<'a>, shared: &Rc<Shared>) -> Result<Value<'a>> {
872 let mut items = Vec::new();
873 let mut sink = Sink {
874 level: Level::Items(&mut items),
875 shared,
876 key: None,
877 };
878 source
879 .read(&mut sink)
880 .map_err(|message| Error::new("U1004").with("message", message))?;
881 Ok(items.into_iter().next().unwrap_or_default())
882 }
883
884 fn unread(&self) -> Option<&'a JsonValue> {
886 match self {
887 Value::Array(a) => a.unread(),
888 Value::Object(o) => o.unread(),
889 _ => None,
890 }
891 }
892
893 pub fn to_json(&self) -> Option<JsonValue> {
897 self.to_json_at(0)
898 }
899
900 fn to_json_at(&self, depth: usize) -> Option<JsonValue> {
902 if let Some(json) = self.unread() {
903 return Some(copy_json(json, depth));
904 }
905 Some(match self {
906 Value::Undefined | Value::Function(_) => return None,
907 Value::Null => JsonValue::Null,
908 Value::Bool(b) => JsonValue::Bool(*b),
909 Value::Number(n) => json_number(*n),
910 Value::String(s) => JsonValue::String(s.to_string()),
911 Value::Array(a) => JsonValue::Array(
912 a.items()
913 .iter()
914 .map(|v| nest(depth + 1, || v.to_json_at(depth + 1)).unwrap_or(JsonValue::Null))
915 .collect(),
916 ),
917 Value::Object(o) => JsonValue::Object(
918 o.borrow()
919 .iter()
920 .filter_map(|(k, v)| {
921 nest(depth + 1, || v.to_json_at(depth + 1)).map(|j| (k.to_string(), j))
922 })
923 .collect(),
924 ),
925 })
926 }
927
928 pub(crate) fn to_json_within(
933 &self,
934 limit: usize,
935 ) -> std::result::Result<Option<JsonValue>, TooLarge> {
936 let mut budget = limit;
937 self.to_json_spending(&mut budget, 0)
938 }
939
940 pub(crate) fn to_json_spending(
946 &self,
947 budget: &mut usize,
948 depth: usize,
949 ) -> std::result::Result<Option<JsonValue>, TooLarge> {
950 self.write_spending(&mut JsonBuilder, budget, depth)
951 }
952
953 pub(crate) fn write_spending<B: Builder>(
956 &self,
957 builder: &mut B,
958 budget: &mut usize,
959 depth: usize,
960 ) -> std::result::Result<Option<B::Value>, TooLarge> {
961 if let Some(json) = self.unread() {
962 return write_json_within(json, builder, budget, depth).map(Some);
963 }
964 if matches!(self, Value::Array(_) | Value::Object(_)) && depth >= MAX_NESTING {
965 return Err(TooLarge::Nesting);
966 }
967 Ok(Some(match self {
968 Value::Undefined | Value::Function(_) => return Ok(None),
969 Value::Null => {
970 charge(budget, 4)?;
971 builder.null()
972 }
973 Value::Bool(b) => {
974 charge(budget, if *b { 4 } else { 5 })?;
975 builder.bool(*b)
976 }
977 Value::Number(n) => {
978 charge(budget, number_len(*n))?;
979 write_number(builder, *n)
980 }
981 Value::String(s) => {
982 charge(budget, s.len() + 2)?;
983 builder.string(s)
984 }
985 Value::Array(a) => {
986 let items = a.items();
987 charge(budget, 1 + items.len().max(1))?;
988 let mut out = builder.array(items.len());
989 for v in items.iter() {
990 let item = match v {
991 Value::Undefined | Value::Function(_) => {
992 charge(budget, 4)?;
993 builder.null()
994 }
995 v => {
996 match nest(depth + 1, || v.write_spending(builder, budget, depth + 1))?
997 {
998 Some(item) => item,
999 None => builder.null(),
1000 }
1001 }
1002 };
1003 builder.push(&mut out, item);
1004 }
1005 builder.end_array(out)
1006 }
1007 Value::Object(o) => {
1008 let o = o.borrow();
1009 charge(budget, if o.is_empty() { 2 } else { 1 })?;
1010 let mut out = builder.object(o.len());
1011 for (k, v) in o.iter() {
1012 if let Some(value) = match v {
1013 Value::Undefined | Value::Function(_) => None,
1014 v => {
1015 charge(budget, k.len() + 4)?;
1016 nest(depth + 1, || v.write_spending(builder, budget, depth + 1))?
1017 }
1018 } {
1019 builder.insert(&mut out, k, value);
1020 }
1021 }
1022 builder.end_object(out)
1023 }
1024 }))
1025 }
1026
1027 pub(crate) fn to_json_detail(&self) -> Option<JsonValue> {
1030 self.to_json_within(crate::eval::DEFAULT_MAX_RESULT_SIZE)
1031 .unwrap_or(None)
1032 }
1033}
1034
1035pub trait Source<'a> {
1042 fn read(&self, sink: &mut Sink<'_, 'a>) -> std::result::Result<(), String>;
1051
1052 fn read_field(&self, key: &str, sink: &mut Sink<'_, 'a>) -> std::result::Result<bool, String> {
1063 let _ = (key, sink);
1064 Ok(false)
1065 }
1066}
1067
1068pub trait Sources<'a> {
1075 fn read(&self, index: u32, sink: &mut Sink<'_, 'a>) -> std::result::Result<(), String>;
1077
1078 fn read_field(
1081 &self,
1082 index: u32,
1083 key: &str,
1084 sink: &mut Sink<'_, 'a>,
1085 ) -> std::result::Result<bool, String> {
1086 let _ = (index, key, sink);
1087 Ok(false)
1088 }
1089}
1090
1091pub struct Sink<'s, 'a> {
1093 level: Level<'s, 'a>,
1094 shared: &'s Rc<Shared>,
1095 key: Option<Rc<str>>,
1096}
1097
1098enum Level<'s, 'a> {
1099 Items(&'s mut Vec<Value<'a>>),
1100 Fields(&'s mut Map<'a>),
1101 Field(&'s mut Value<'a>),
1103}
1104
1105impl<'a> Sink<'_, 'a> {
1106 pub fn reserve(&mut self, additional: usize) {
1109 let additional = additional.min(1 << 16);
1111 match &mut self.level {
1112 Level::Items(items) => items.reserve(additional),
1113 Level::Fields(map) => map.reserve(additional),
1114 Level::Field(_) => {}
1115 }
1116 }
1117
1118 pub fn key(&mut self, key: &str) {
1122 if let Level::Fields(_) = self.level {
1123 self.key = Some(self.shared.keys.borrow_mut().get(key));
1124 }
1125 }
1126
1127 pub fn null(&mut self) {
1129 self.push(Value::Null);
1130 }
1131
1132 pub fn bool(&mut self, value: bool) {
1134 self.push(Value::Bool(value));
1135 }
1136
1137 pub fn number(&mut self, value: f64) {
1140 self.push(Value::Number(value));
1141 }
1142
1143 pub fn string(&mut self, value: &str) {
1145 self.push(Value::string(value));
1146 }
1147
1148 pub fn json_members(&mut self, text: &str) -> std::result::Result<(), String> {
1155 let value: Value<'a> =
1156 crate::document::parse_value(text, &mut self.shared.keys.borrow_mut())
1157 .map_err(|e| e.to_string())?;
1158 match (value, &mut self.level) {
1159 (Value::Array(array), Level::Items(items)) => match Rc::try_unwrap(array) {
1160 Ok(mut array) => items.extend(std::mem::take(&mut array.items)),
1161 Err(array) => items.extend(array.items().iter().cloned()),
1162 },
1163 (Value::Object(object), Level::Fields(map)) => match Rc::try_unwrap(object) {
1164 Ok(object) => map.extend(object.map.take()),
1165 Err(object) => {
1166 map.extend(object.borrow().iter().map(|(k, v)| (k.clone(), v.clone())))
1167 }
1168 },
1169 (_, Level::Items(_)) => return Err("expected a JSON array".into()),
1170 (_, Level::Fields(_)) => return Err("expected a JSON object".into()),
1171 (_, Level::Field(_)) => return Err("a field is written as one value".into()),
1172 }
1173 Ok(())
1174 }
1175
1176 pub fn array(&mut self, source: impl Source<'a> + 'a) {
1178 let pending = self.pending(Rc::new(Only(source)));
1179 self.push(Value::lazy_array(pending, 0));
1180 }
1181
1182 pub fn object(&mut self, source: impl Source<'a> + 'a) {
1184 let pending = self.pending(Rc::new(Only(source)));
1185 self.push(Value::lazy_object(pending, 0));
1186 }
1187
1188 pub fn array_of<S: Sources<'a> + 'a>(&mut self, sources: &Rc<S>, index: u32) {
1191 let pending = self.pending(sources.clone());
1192 self.push(Value::lazy_array(pending, index));
1193 }
1194
1195 pub fn object_of<S: Sources<'a> + 'a>(&mut self, sources: &Rc<S>, index: u32) {
1198 let pending = self.pending(sources.clone());
1199 self.push(Value::lazy_object(pending, index));
1200 }
1201
1202 fn pending(&self, sources: Rc<dyn Sources<'a> + 'a>) -> Pending<'a> {
1203 Pending {
1204 origin: Origin::Source(sources),
1205 shared: self.shared.clone(),
1206 }
1207 }
1208
1209 fn push(&mut self, value: Value<'a>) {
1210 match &mut self.level {
1211 Level::Items(items) => items.push(value),
1212 Level::Fields(map) => {
1213 if let Some(key) = self.key.take() {
1214 map.insert(key, value);
1215 }
1216 }
1217 Level::Field(field) => {
1218 if field.is_undefined() {
1219 **field = value;
1220 }
1221 }
1222 }
1223 }
1224}
1225
1226fn copy_json(json: &JsonValue, depth: usize) -> JsonValue {
1230 match json {
1231 JsonValue::Number(n) => json_number(n.as_f64().unwrap_or(f64::NAN)),
1232 JsonValue::Array(items) => JsonValue::Array(
1233 items
1234 .iter()
1235 .map(|v| nest(depth + 1, || copy_json(v, depth + 1)))
1236 .collect(),
1237 ),
1238 JsonValue::Object(fields) => JsonValue::Object(
1239 fields
1240 .iter()
1241 .map(|(k, v)| (k.clone(), nest(depth + 1, || copy_json(v, depth + 1))))
1242 .collect(),
1243 ),
1244 other => other.clone(),
1245 }
1246}
1247
1248fn write_json_within<B: Builder>(
1251 json: &JsonValue,
1252 builder: &mut B,
1253 budget: &mut usize,
1254 depth: usize,
1255) -> std::result::Result<B::Value, TooLarge> {
1256 if matches!(json, JsonValue::Array(_) | JsonValue::Object(_)) && depth >= MAX_NESTING {
1257 return Err(TooLarge::Nesting);
1258 }
1259 Ok(match json {
1260 JsonValue::Null => {
1261 charge(budget, 4)?;
1262 builder.null()
1263 }
1264 JsonValue::Bool(b) => {
1265 charge(budget, if *b { 4 } else { 5 })?;
1266 builder.bool(*b)
1267 }
1268 JsonValue::Number(n) => {
1269 let n = n.as_f64().unwrap_or(f64::NAN);
1270 charge(budget, number_len(n))?;
1271 write_number(builder, n)
1272 }
1273 JsonValue::String(s) => {
1274 charge(budget, s.len() + 2)?;
1275 builder.string(s)
1276 }
1277 JsonValue::Array(items) => {
1278 charge(budget, 1 + items.len().max(1))?;
1279 let mut out = builder.array(items.len());
1280 for v in items {
1281 let item = nest(depth + 1, || {
1282 write_json_within(v, builder, budget, depth + 1)
1283 })?;
1284 builder.push(&mut out, item);
1285 }
1286 builder.end_array(out)
1287 }
1288 JsonValue::Object(fields) => {
1289 charge(budget, if fields.is_empty() { 2 } else { 1 })?;
1290 let mut out = builder.object(fields.len());
1291 for (k, v) in fields {
1292 charge(budget, k.len() + 4)?;
1293 let v = nest(depth + 1, || {
1294 write_json_within(v, builder, budget, depth + 1)
1295 })?;
1296 builder.insert(&mut out, k, v);
1297 }
1298 builder.end_object(out)
1299 }
1300 })
1301}
1302
1303#[inline]
1305fn write_number<B: Builder>(builder: &mut B, n: f64) -> B::Value {
1306 if n.is_finite() {
1307 builder.number(n)
1308 } else {
1309 builder.null()
1310 }
1311}
1312
1313pub(crate) struct JsonBuilder;
1315
1316impl Builder for JsonBuilder {
1317 type Value = JsonValue;
1318 type Array = Vec<JsonValue>;
1319 type Object = serde_json::Map<String, JsonValue>;
1320
1321 fn null(&mut self) -> JsonValue {
1322 JsonValue::Null
1323 }
1324
1325 fn bool(&mut self, value: bool) -> JsonValue {
1326 JsonValue::Bool(value)
1327 }
1328
1329 #[inline]
1330 fn number(&mut self, value: f64) -> JsonValue {
1331 json_number(value)
1332 }
1333
1334 fn string(&mut self, value: &str) -> JsonValue {
1335 JsonValue::String(value.to_owned())
1336 }
1337
1338 fn array(&mut self, len: usize) -> Vec<JsonValue> {
1339 Vec::with_capacity(len)
1340 }
1341
1342 fn push(&mut self, array: &mut Vec<JsonValue>, item: JsonValue) {
1343 array.push(item);
1344 }
1345
1346 fn end_array(&mut self, array: Vec<JsonValue>) -> JsonValue {
1347 JsonValue::Array(array)
1348 }
1349
1350 fn object(&mut self, len: usize) -> serde_json::Map<String, JsonValue> {
1351 serde_json::Map::with_capacity(len)
1352 }
1353
1354 fn insert(
1355 &mut self,
1356 object: &mut serde_json::Map<String, JsonValue>,
1357 key: &str,
1358 value: JsonValue,
1359 ) {
1360 object.insert(key.to_owned(), value);
1361 }
1362
1363 fn end_object(&mut self, object: serde_json::Map<String, JsonValue>) -> JsonValue {
1364 JsonValue::Object(object)
1365 }
1366}
1367
1368pub(crate) trait Inspect: std::fmt::Debug {
1372 fn to_json(&self) -> Option<JsonValue>;
1373 fn to_json_within(&self, limit: usize) -> std::result::Result<Option<JsonValue>, TooLarge>;
1374 fn capture(&self, limits: &crate::audit::CaptureLimits) -> Option<JsonValue>;
1375 fn as_bool(&self) -> Option<bool>;
1376 fn signature_symbol(&self) -> char;
1377}
1378
1379impl Inspect for Value<'_> {
1380 fn to_json(&self) -> Option<JsonValue> {
1381 Value::to_json_within(self, usize::MAX).unwrap_or(None)
1384 }
1385
1386 fn to_json_within(&self, limit: usize) -> std::result::Result<Option<JsonValue>, TooLarge> {
1387 Value::to_json_within(self, limit)
1388 }
1389
1390 fn capture(&self, limits: &crate::audit::CaptureLimits) -> Option<JsonValue> {
1391 crate::audit::capture(self, limits, 0)
1392 }
1393
1394 fn as_bool(&self) -> Option<bool> {
1395 match self {
1396 Value::Bool(b) => Some(*b),
1397 _ => None,
1398 }
1399 }
1400
1401 fn signature_symbol(&self) -> char {
1402 Value::signature_symbol(self)
1403 }
1404}
1405
1406fn charge(budget: &mut usize, bytes: usize) -> std::result::Result<(), TooLarge> {
1408 *budget = budget.checked_sub(bytes).ok_or(TooLarge::Size)?;
1409 Ok(())
1410}
1411
1412pub(crate) const MAX_NESTING: usize = 1_000;
1416
1417#[inline]
1421pub(crate) fn nest<R>(depth: usize, step: impl FnOnce() -> R) -> R {
1422 if depth.is_multiple_of(16) {
1423 crate::stack::grow(step)
1424 } else {
1425 step()
1426 }
1427}
1428
1429pub(crate) fn too_deep() -> Error {
1431 Error::new("U1001").with(
1432 "message",
1433 format!("A value is nested more than {MAX_NESTING} levels deep"),
1434 )
1435}
1436
1437#[derive(Debug, Clone, Copy)]
1439pub(crate) enum TooLarge {
1440 Size,
1441 Nesting,
1442}
1443
1444impl TooLarge {
1445 pub(crate) fn error(self, size: impl FnOnce() -> String) -> Error {
1447 match self {
1448 TooLarge::Size => Error::new("U1001").with("message", size()),
1449 TooLarge::Nesting => too_deep(),
1450 }
1451 }
1452}
1453
1454fn number_len(n: f64) -> usize {
1457 if !n.is_finite() {
1458 4
1459 } else if n.fract() == 0.0 && n.abs() < 9.007_199_254_740_992e15 {
1460 let mut len = usize::from(n < 0.0) + 1;
1461 let mut rest = (n as i64).unsigned_abs() / 10;
1462 while rest > 0 {
1463 len += 1;
1464 rest /= 10;
1465 }
1466 len
1467 } else {
1468 ryu_js::Buffer::new().format(n).len()
1469 }
1470}
1471
1472pub(crate) fn finite<'a>(n: f64) -> Result<Value<'a>> {
1474 if n.is_infinite() {
1475 Err(Error::new("D1001").with("value", json_number(n)))
1476 } else {
1477 Ok(Value::Number(n))
1478 }
1479}
1480
1481pub(crate) fn json_number(n: f64) -> JsonValue {
1483 if n.fract() == 0.0 && n.abs() < 9.007_199_254_740_992e15 {
1484 JsonValue::from(n as i64)
1485 } else {
1486 serde_json::Number::from_f64(n).map_or(JsonValue::Null, JsonValue::Number)
1487 }
1488}
1489
1490pub(crate) fn js_number(n: f64) -> String {
1492 if n == 0.0 {
1493 return "0".into();
1494 }
1495 ryu_js::Buffer::new().format(n).to_owned()
1496}
1497
1498pub(crate) fn round15(n: f64) -> f64 {
1500 if n.fract() == 0.0 || !n.is_finite() {
1501 return n;
1502 }
1503 format!("{n:.14e}").parse().unwrap_or(n)
1504}
1505
1506pub(crate) fn js_string_cmp(a: &str, b: &str) -> Ordering {
1508 a.encode_utf16().cmp(b.encode_utf16())
1509}
1510
1511pub(crate) fn write_json_string(out: &mut String, s: &str) {
1513 out.push('"');
1514 for c in s.chars() {
1515 match c {
1516 '"' => out.push_str("\\\""),
1517 '\\' => out.push_str("\\\\"),
1518 '\u{8}' => out.push_str("\\b"),
1519 '\u{c}' => out.push_str("\\f"),
1520 '\n' => out.push_str("\\n"),
1521 '\r' => out.push_str("\\r"),
1522 '\t' => out.push_str("\\t"),
1523 c if (c as u32) < 0x20 => {
1524 let _ = write!(out, "\\u{:04x}", c as u32);
1525 }
1526 c => out.push(c),
1527 }
1528 }
1529 out.push('"');
1530}
1531
1532pub(crate) fn stringify<'a>(value: &Value<'a>, pretty: bool, limit: usize) -> Result<String> {
1535 let mut out = String::new();
1536 let value = match value {
1537 Value::Array(a) if a.has(OUTER_WRAPPER) && !a.items().is_empty() => &a.items()[0],
1538 v => v,
1539 };
1540 write_json(&mut out, value, pretty, 0, limit)?;
1541 Ok(out)
1542}
1543
1544pub(crate) fn string_too_long(limit: usize) -> Error {
1546 Error::new("U1001").with(
1547 "message",
1548 format!("A string would exceed the size limit of {limit} bytes"),
1549 )
1550}
1551
1552fn write_json<'a>(
1555 out: &mut String,
1556 value: &Value<'a>,
1557 pretty: bool,
1558 depth: usize,
1559 limit: usize,
1560) -> Result<()> {
1561 let newline = |out: &mut String, depth: usize| {
1562 if pretty {
1563 out.push('\n');
1564 out.push_str(&" ".repeat(depth));
1565 }
1566 };
1567 match value {
1568 Value::Undefined | Value::Null => out.push_str("null"),
1569 Value::Bool(b) => out.push_str(if *b { "true" } else { "false" }),
1570 Value::Number(n) => {
1571 if !value.is_numeric()? {
1572 out.push_str("null"); } else {
1574 out.push_str(&js_number(round15(*n)));
1575 }
1576 }
1577 Value::String(s) => write_json_string(out, s),
1578 Value::Function(_) => out.push_str("\"\""),
1579 Value::Array(_) | Value::Object(_) if depth >= MAX_NESTING => return Err(too_deep()),
1580 Value::Array(a) => {
1581 if a.items().is_empty() {
1582 out.push_str("[]");
1583 return Ok(());
1584 }
1585 out.push('[');
1586 for (i, item) in a.items().iter().enumerate() {
1587 if i > 0 {
1588 out.push(',');
1589 }
1590 newline(out, depth + 1);
1591 nest(depth + 1, || {
1592 write_json(out, item, pretty, depth + 1, limit)
1593 })?;
1594 }
1595 newline(out, depth);
1596 out.push(']');
1597 }
1598 Value::Object(o) => {
1599 let o = o.borrow();
1600 let mut first = true;
1601 out.push('{');
1602 for (k, v) in o.iter() {
1603 if v.is_undefined() {
1604 continue;
1605 }
1606 if !first {
1607 out.push(',');
1608 }
1609 first = false;
1610 newline(out, depth + 1);
1611 write_json_string(out, k);
1612 out.push(':');
1613 if pretty {
1614 out.push(' ');
1615 }
1616 nest(depth + 1, || write_json(out, v, pretty, depth + 1, limit))?;
1617 }
1618 if !first {
1619 newline(out, depth);
1620 }
1621 out.push('}');
1622 }
1623 }
1624 if out.len() > limit {
1625 return Err(string_too_long(limit));
1626 }
1627 Ok(())
1628}
1629
1630impl std::fmt::Debug for Value<'_> {
1631 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1632 match self {
1633 Value::Undefined => f.write_str("undefined"),
1634 Value::Function(_) => f.write_str("<function>"),
1635 other => match stringify(other, false, crate::eval::DEFAULT_MAX_STRING_LENGTH) {
1636 Ok(s) => f.write_str(&s),
1637 Err(_) => f.write_str("<invalid>"),
1638 },
1639 }
1640 }
1641}
1642
1643#[cfg(test)]
1644mod tests {
1645 use super::*;
1646
1647 #[test]
1648 fn numbers_print_like_javascript() {
1649 assert_eq!(js_number(1.0), "1");
1650 assert_eq!(js_number(-0.0), "0");
1651 assert_eq!(js_number(0.1 + 0.2), "0.30000000000000004");
1652 assert_eq!(js_number(round15(0.1 + 0.2)), "0.3");
1653 assert_eq!(js_number(1e21), "1e+21");
1654 assert_eq!(js_number(123456789012.5), "123456789012.5");
1655 }
1656
1657 #[test]
1658 fn json_size_is_the_length_of_the_compact_text() {
1659 let v = Value::from_json(&serde_json::json!({
1660 "a": [1, -25, 2.5, null, true, false, 1e21],
1661 "bc": "xyz",
1662 "d": {},
1663 "e": [],
1664 "f": [{}]
1665 }));
1666 let len = stringify(&v, false, usize::MAX).unwrap().len();
1667 assert_eq!(v.to_json_within(len).unwrap(), v.to_json());
1668 assert!(v.to_json_within(len - 1).is_err());
1669 }
1670
1671 #[test]
1672 fn stringify_matches_json_stringify() {
1673 let v = Value::from_json(&serde_json::json!({"a": [1, 2.5, null], "b": "x\"y\n", "c": {}}));
1674 assert_eq!(
1675 stringify(&v, false, usize::MAX).unwrap(),
1676 r#"{"a":[1,2.5,null],"b":"x\"y\n","c":{}}"#
1677 );
1678 assert_eq!(
1679 stringify(&v, true, usize::MAX).unwrap(),
1680 "{\n \"a\": [\n 1,\n 2.5,\n null\n ],\n \"b\": \"x\\\"y\\n\",\n \"c\": {}\n}"
1681 );
1682 }
1683
1684 #[test]
1685 fn a_field_read_alone_is_kept_when_its_object_is_read_whole() {
1686 let json = serde_json::json!({"a": {"b": 1}, "c": [2], "d": "x"});
1687 let shared = Shared::new();
1688 let Value::Object(o) = Value::lazy(&json, &shared) else {
1689 panic!("an object");
1690 };
1691 let (Value::Object(a), Value::Array(c)) = (o.get("a"), o.get("c")) else {
1692 panic!("fields");
1693 };
1694 assert!(o.get("missing").is_undefined());
1695 assert!(!o.is_unread());
1696 let Value::Object(again) = o.get("a") else {
1697 panic!("a field");
1698 };
1699 assert!(Rc::ptr_eq(&a, &again));
1700 let map = o.borrow();
1701 assert_eq!(
1702 map.keys().map(|k| &**k).collect::<Vec<_>>(),
1703 ["a", "c", "d"]
1704 );
1705 assert!(matches!(&map["a"], Value::Object(whole) if Rc::ptr_eq(whole, &a)));
1706 assert!(matches!(&map["c"], Value::Array(whole) if Rc::ptr_eq(whole, &c)));
1707 }
1708
1709 #[test]
1710 fn equality() {
1711 let a = Value::from_json(&serde_json::json!({"x": [1, {"y": 2}]}));
1712 let b = Value::from_json(&serde_json::json!({"x": [1.0, {"y": 2}]}));
1713 assert!(a.deep_eq(&b).unwrap());
1714 assert!(!a.strict_eq(&b));
1715 assert_eq!(js_string_cmp("a", "b"), Ordering::Less);
1716 }
1717}