Skip to main content

jlens_core/
value.rs

1//! The run-time value model (see ADR 0003).
2//!
3//! JSONata distinguishes *undefined* from `null`, and *sequences* (results of path navigation,
4//! which collapse when empty or singleton) from arrays. Arrays therefore carry flags, set and
5//! read exactly where jsonata-js sets and reads the corresponding properties on its arrays.
6//! Objects are shared and mutable (`Rc<RefCell<…>>`) because the transform operator updates the
7//! objects that its pattern selects in place.
8
9use 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
27/// The fields of an object, in insertion order. Keys are shared: the objects of a converted
28/// document that have the same key point to one string (see [`Keys`]).
29pub(crate) type Map<'a> = IndexMap<Rc<str>, Value<'a>, foldhash::fast::RandomState>;
30
31/// The keys met while converting one document, so that objects with the same keys (the items
32/// of an array, typically) share them instead of allocating each.
33#[derive(Default)]
34pub(crate) struct Keys(HashSet<Rc<str>, foldhash::fast::RandomState>);
35
36impl Keys {
37    /// Past this many distinct keys, new keys are allocated without being remembered: a
38    /// document whose keys are all different (identifiers used as keys) gains nothing from
39    /// the table.
40    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/// What the lazy values of one evaluation share (ADR 0010): the table of their keys, and the
55/// first error of a [`Source`] that failed to read a level.
56#[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    /// Whether a level could not be read.
69    #[inline]
70    pub(crate) fn failed(&self) -> bool {
71        self.failed.get()
72    }
73
74    /// The `U1004` error of the first level that could not be read.
75    #[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
88/// The part of the input that a lazy array or object stands for, not read yet (ADR 0010). The
89/// first access to the array's items or the object's map reads one level of it.
90struct Pending<'a> {
91    origin: Origin<'a>,
92    shared: Rc<Shared>,
93}
94
95enum Origin<'a> {
96    Json(&'a JsonValue),
97    /// A member of sources held together, or a source alone (an [`Only`]). The member's index
98    /// is kept by its array or object, in room their layout leaves free, so that a lazy value
99    /// stays as small as one over JSON.
100    Source(Rc<dyn Sources<'a> + 'a>),
101}
102
103/// A source written alone, with [`Sink::array`] or [`Sink::object`]: the only member, at index 0.
104struct 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    /// The JSON this stands for, when it is JSON.
123    fn json(&self) -> Option<&'a JsonValue> {
124        match self.origin {
125            Origin::Json(json) => Some(json),
126            Origin::Source(_) => None,
127        }
128    }
129
130    /// Reads the level of the member `member` of `sources` into `level`. A source that fails
131    /// leaves the level empty, and its error is recorded for the evaluation (ADR 0010,
132    /// decision 6).
133    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    /// Reads the field `key` from a source: `None` when the source reads its object whole only,
150    /// undefined when the object has no such field or the source failed (its error is then
151    /// recorded, as for a level).
152    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/// A JSONata value.
176#[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
195/// An array, with the flags jsonata-js attaches to its arrays.
196pub(crate) struct Array<'a> {
197    /// The items of an array built by the evaluation, or of a document; empty when the array
198    /// is lazy.
199    items: Vec<Value<'a>>,
200    flags: Cell<u8>,
201    /// The items of an array of the input, read on first access. They are kept apart so that
202    /// the other arrays read a plain field.
203    lazy: Option<Box<LazyItems<'a>>>,
204}
205
206struct LazyItems<'a> {
207    pending: Pending<'a>,
208    /// The array's index among sources held together.
209    member: u32,
210    items: OnceCell<Vec<Value<'a>>>,
211}
212
213impl<'a> LazyItems<'a> {
214    /// The items, read from the input on the first call.
215    #[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    /// The items, read from the input first if the array is lazy.
235    #[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    /// The input JSON this array stands for, when it has not been read.
244    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    /// Whether the array has not been read from the input yet. Such an array holds only values
252    /// of the input.
253    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
283/// An object. It is shared and mutable because the transform operator updates in place the
284/// objects that its pattern selects.
285pub(crate) struct Object<'a> {
286    /// The fields; empty until a lazy object is read, or holding the fields read alone.
287    map: RefCell<Map<'a>>,
288    /// The input a lazy object stands for. It is a plain field, so that the other objects
289    /// cost one test of it.
290    pending: Option<Pending<'a>>,
291    read: Cell<Read>,
292    /// The index of a lazy object that is a member of sources held together.
293    member: u32,
294}
295
296/// How much of a lazy object has been read into its map.
297#[derive(Clone, Copy, PartialEq, Eq)]
298enum Read {
299    Nothing,
300    /// Some arrays and objects of its fields, each read alone by a path step (ADR 0010,
301    /// amendment).
302    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    /// Reads the fields of a lazy object into its map, which nothing borrows yet: every
318    /// borrow goes through `cell`. The fields read alone before keep their values, so that a
319    /// value read twice is the same value.
320    #[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    /// The field `key`, or undefined. A lazy object not read whole reads that field alone
356    /// when its input can, and keeps it when it is an array or an object.
357    #[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                // `serde_json` hashes keys with SipHash: comparing them costs less in a small
376                // object.
377                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        // Only arrays and objects are kept: they are the values whose identity shows (the
397        // transform changes them in place), and keeping a scalar would cost more than reading
398        // it again.
399        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    /// The fields, read from the input first if the object is lazy.
408    #[inline]
409    pub fn borrow(&self) -> Ref<'_, Map<'a>> {
410        self.cell().borrow()
411    }
412
413    /// The fields, mutably, read from the input first if the object is lazy.
414    #[inline]
415    pub fn borrow_mut(&self) -> RefMut<'_, Map<'a>> {
416        self.cell().borrow_mut()
417    }
418
419    /// The input JSON this object stands for, when it has not been read.
420    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    /// Whether nothing of the object has been read from the input yet. Such an object holds
428    /// only values of the input.
429    pub fn is_unread(&self) -> bool {
430        self.pending.is_some() && self.read.get() == Read::Nothing
431    }
432}
433
434// Arrays and objects nested deeper than the native stack allows (built by a tail-recursive
435// function, or read from a `Source`) must be dropped too. The drops of those that hold arrays
436// or objects of their own count how deep they are nested in one another, and past
437// `DROP_DEPTH` levels, the arrays and objects inside are dropped without recursion. The others,
438// most of them, drop as usual.
439impl 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        // Moved out with the same hasher, which costs no allocation; clearing it in place would
464        // reset its table first.
465        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
476/// Whether a value is an array or object that nothing else holds, which dropping it drops.
477fn 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
485/// How deep drops nest before the values inside are released from a list instead.
486const DROP_DEPTH: usize = 100;
487
488thread_local! {
489    static DROPS: Cell<usize> = const { Cell::new(0) };
490}
491
492/// Runs `drop`, a level deeper in the drops of arrays and objects; it is told whether that is
493/// past [`DROP_DEPTH`].
494fn 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
503/// Calls `f` with each value of `items` that is not an array, in order, entering the arrays
504/// nested in them. The walk keeps its own stack, so arrays nested at any depth are walked.
505pub(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
523/// Drops values, emptying the arrays and objects that only they hold one at a time, from a
524/// list of their own, rather than each inside the drop of its parent.
525fn 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
548/// A function value.
549pub(crate) enum Function<'a> {
550    /// A JSONata `function(...)`, or a tail-call thunk.
551    Lambda(Lambda<'a>),
552    /// A built-in function.
553    Native(&'static Native),
554    /// A function of the host application.
555    Host(HostFunction),
556    /// A built-in or host function with some arguments supplied (`$f(?, 2)`); `None` marks a
557    /// `?`.
558    Partial {
559        target: Rc<Function<'a>>,
560        args: Vec<Option<Value<'a>>>,
561    },
562    /// The function produced by a transform expression.
563    Transform {
564        def: Arc<TransformDef>,
565        env: Env<'a>,
566        span: Span,
567        position: usize,
568    },
569    /// A regular expression literal, which is callable as a matcher.
570    Regex(Rc<Regex>),
571    /// The `next()` function of a regex match object.
572    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    /// The parameters still to be supplied, when fewer than `def.params` (partial application).
582    pub params: Option<Rc<[String]>>,
583    /// Whether arguments are checked against `def.signature`; partial applications are not.
584    pub validate: bool,
585    pub input: Value<'a>,
586    pub env: Env<'a>,
587}
588
589impl<'a> Function<'a> {
590    /// Number of parameters, used by higher-order functions to decide which arguments to pass.
591    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    /// A new sequence (jsonata-js `createSequence`).
622    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    /// Whether this is an array with `flag` set.
659    pub fn has_flag(&self, flag: u8) -> bool {
660        self.as_array().is_some_and(|a| a.has(flag))
661    }
662
663    /// The items of an array, or the value itself as a single item (`undefined` included, like
664    /// `createSequence(value)` in jsonata-js).
665    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    /// jsonata-js `isNumeric`: a number that is not NaN. Infinite numbers raise D1001.
673    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    /// The symbol used by function signatures: `s n b l a o f`, or `m` for undefined.
699    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    /// jsonata-js `isArrayOfNumbers`.
713    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    /// jsonata-js `isArrayOfStrings`.
728    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    /// Strict equality (`===`) as used by the `in` operator.
736    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    /// Deep equality (jsonata-js `isDeepEqual`), used by `=` and `!=`. Values nested more than
750    /// [`MAX_NESTING`] levels deep are not compared: `U1001`.
751    pub fn deep_eq(&self, other: &Value<'a>) -> Result<bool> {
752        self.deep_eq_at(other, 0)
753    }
754
755    /// [`Value::deep_eq`] for values nested in `depth` arrays and objects.
756    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    /// Converts input JSON into a value.
799    pub fn from_json(json: &JsonValue) -> Value<'a> {
800        Value::from_json_with(json, &mut Keys::default(), 0)
801    }
802
803    /// [`Value::from_json`] for JSON nested in `depth` arrays and objects.
804    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    /// A value over input JSON that reads it one level at a time, on first access (ADR 0010):
829    /// an array or object is converted only when the evaluation reads it. `keys` is shared by
830    /// the lazy values of one evaluation.
831    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    /// The input of an evaluation, read from a [`Source`] that writes it as the only value of
870    /// its level (nothing for undefined). The error of a source that fails is returned.
871    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    /// The input JSON an array or object stands for, when it has not been read.
885    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    /// Converts a result into JSON, following `JSON.stringify`: undefined and functions are
894    /// dropped from objects and become `null` in arrays; a top-level one yields `None`. It has
895    /// no nesting limit: it converts documents, whose depth their JSON bounds.
896    pub fn to_json(&self) -> Option<JsonValue> {
897        self.to_json_at(0)
898    }
899
900    /// [`Value::to_json`] for a value nested in `depth` arrays and objects.
901    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    /// Converts a value into JSON like [`Value::to_json`], failing when its compact JSON text
929    /// would be longer than `limit` bytes, or when it is nested more than [`MAX_NESTING`]
930    /// levels deep. The size is counted while converting, which stops as soon as it is
931    /// exceeded.
932    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    /// [`Value::to_json`] for a value nested in `depth` arrays and objects, spending the length
941    /// of its compact JSON text from `budget`. Escaped characters count as one byte, and
942    /// numbers about as many bytes as JavaScript prints. A value that appears several times (an
943    /// object bound to a variable and nested in itself, say) counts each time, as it does in
944    /// the text.
945    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    /// Writes a value with `builder` (ADR 0017), as [`Value::to_json_spending`] converts it,
954    /// spending the length of its compact JSON text from `budget`.
955    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    /// The JSON of a value shown in an error detail; `None` when it is undefined, or larger
1028    /// than the default size limit of a result.
1029    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
1035/// Input read one level at a time, for evaluations whose input is not a `serde_json::Value`
1036/// (see [`Expression::evaluate_source`](crate::Expression::evaluate_source) and ADR 0010).
1037///
1038/// A source stands for an array, an object, or the input itself. Each level is read once, on
1039/// the evaluation's first access to it, and only the levels the expression reaches are read.
1040/// A source that borrows nothing implements `Source<'a>` for every `'a`.
1041pub trait Source<'a> {
1042    /// Writes the values of this level to `sink`, in order: the items of an array, the fields
1043    /// of an object (each value after its key, given with [`Sink::key`]), or the input itself
1044    /// as the only value (nothing when it is undefined). Nested arrays and objects are written
1045    /// as new sources, read when the evaluation reaches them.
1046    ///
1047    /// An error stops the evaluation with `U1004`, whose message is the error's. The level is
1048    /// left empty, and the evaluation fails at its next step, before it calls a host function,
1049    /// or before it returns its result.
1050    fn read(&self, sink: &mut Sink<'_, 'a>) -> std::result::Result<(), String>;
1051
1052    /// Writes the value of the field `key` of the object this source stands for, as the only
1053    /// value (nothing when the object has no such field), and returns `true`. A source that
1054    /// reads its object whole only returns `false`, writing nothing; that is the default.
1055    ///
1056    /// A path step calls it on an object not read whole yet. The object keeps an array or an
1057    /// object written this way, so that it is read once; when the object is needed whole, its
1058    /// level is read with [`Source::read`], and the arrays and objects read before keep their
1059    /// values. A scalar is not kept: the step reads it again. Implement it when one field costs
1060    /// less than the whole level, as a lookup in a hash map does. An error stops the
1061    /// evaluation as it does in [`Source::read`].
1062    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
1068/// The sources of several arrays and objects, held together: each is a member, known by its
1069/// index. [`Sink::array`] and [`Sink::object`] allocate each source they are given, besides
1070/// the array or object itself; [`Sink::array_of`] and [`Sink::object_of`] share one value of
1071/// this trait instead, so that the arrays and objects of a level cost one allocation each.
1072///
1073/// A member is read as a [`Source`] is, by the method of the same name, given its index.
1074pub trait Sources<'a> {
1075    /// Writes the values of the member at `index` to `sink`, as [`Source::read`] does.
1076    fn read(&self, index: u32, sink: &mut Sink<'_, 'a>) -> std::result::Result<(), String>;
1077
1078    /// Writes the value of the field `key` of the member at `index`, as [`Source::read_field`]
1079    /// does. A member read whole only returns `false`, writing nothing; that is the default.
1080    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
1091/// Where a [`Source`] writes the values of a level.
1092pub 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    /// The value of one field, read alone: the first value written.
1102    Field(&'s mut Value<'a>),
1103}
1104
1105impl<'a> Sink<'_, 'a> {
1106    /// Tells how many more values the level holds, when the source knows: room is made for
1107    /// them at once. It is only a hint.
1108    pub fn reserve(&mut self, additional: usize) {
1109        // A hint larger than any level, from a source that miscounts, is ignored.
1110        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    /// The key of the next value, in an object; ignored in an array or for the input. In an
1119    /// object, a value written without a key is left out, and a key written again replaces the
1120    /// earlier value, keeping its position.
1121    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    /// Writes `null`.
1128    pub fn null(&mut self) {
1129        self.push(Value::Null);
1130    }
1131
1132    /// Writes a boolean.
1133    pub fn bool(&mut self, value: bool) {
1134        self.push(Value::Bool(value));
1135    }
1136
1137    /// Writes a number. JSON has no NaN or infinity: a source that follows JSON writes `null`
1138    /// for them, as `JSON.stringify` does.
1139    pub fn number(&mut self, value: f64) {
1140        self.push(Value::Number(value));
1141    }
1142
1143    /// Writes a string.
1144    pub fn string(&mut self, value: &str) {
1145        self.push(Value::string(value));
1146    }
1147
1148    /// Writes the items of a JSON array, or the fields of a JSON object, given as text: an
1149    /// array's items in an array, an object's fields in an object. They are converted at once,
1150    /// with everything they hold, rather than one level at a time. When the text is not valid
1151    /// JSON, or nests deeper than 128 levels, nothing is written and the error is returned.
1152    ///
1153    /// Use it for a level that is cheaper to serialize than to write value by value.
1154    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    /// Writes an array, read from `source` when the evaluation reaches it.
1177    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    /// Writes an object, read from `source` when the evaluation reaches it.
1183    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    /// Writes an array, the member at `index` of `sources`, read when the evaluation reaches
1189    /// it.
1190    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    /// Writes an object, the member at `index` of `sources`, read when the evaluation reaches
1196    /// it.
1197    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
1226/// A copy of input JSON, nested in `depth` arrays and objects, with its numbers as
1227/// [`Value::to_json`] writes them: what converting it to a value and back gives, without
1228/// building the value.
1229fn 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
1248/// Writes input JSON nested in `depth` arrays and objects with `builder`, as [`copy_json`] copies
1249/// it, spending the length of the text from `budget` as [`Value::to_json_spending`] does.
1250fn 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/// Writes a number, or `null` for one that is not finite.
1304#[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
1313/// Builds `serde_json` values: the result of [`Value::to_json_within`].
1314pub(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
1368/// A value of any evaluation behind a trait object, whatever the lifetime of its input. Public
1369/// types that show a value (`audit::ValueRef`, `HostCall`) hold one, so that they keep a single
1370/// lifetime (ADR 0010).
1371pub(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        // Within the nesting limit: a tracer may keep the JSON, and a deeper one would
1382        // overflow the stack when dropped.
1383        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
1406/// Takes `bytes` from `budget`, failing when there are not enough left.
1407fn charge(budget: &mut usize, bytes: usize) -> std::result::Result<(), TooLarge> {
1408    *budget = budget.checked_sub(bytes).ok_or(TooLarge::Size)?;
1409    Ok(())
1410}
1411
1412/// The deepest arrays and objects may nest in a value that is converted to JSON, compared or
1413/// serialized. jsonata-js is limited by the JavaScript stack; jlens fails cleanly instead, and
1414/// the JSON it returns can then be dropped or serialized by recursive code (`serde_json`).
1415pub(crate) const MAX_NESTING: usize = 1_000;
1416
1417/// Runs the step of a recursive walk over values that enters level `depth`, growing the stack
1418/// natively every 16 levels: the red zone of [`crate::stack::grow`] covers the frames between,
1419/// and checking at each value would slow the walks down.
1420#[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
1429/// The error of a value nested more than [`MAX_NESTING`] levels deep.
1430pub(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/// A value whose JSON text would exceed a size limit, or the nesting limit.
1438#[derive(Debug, Clone, Copy)]
1439pub(crate) enum TooLarge {
1440    Size,
1441    Nesting,
1442}
1443
1444impl TooLarge {
1445    /// The `U1001` error, whose message is `size` for a value too large.
1446    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
1454/// The length of a number in JSON text: its digits for an integer, about as many as
1455/// JavaScript prints otherwise, and 4 for `null` (a number that is not finite).
1456fn 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
1472/// A computed number, or D1001 when it overflowed to infinity, which JSON cannot hold.
1473pub(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
1481/// A number as JSON: integral values become JSON integers, non-finite ones `null`.
1482pub(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
1490/// Formats a number exactly like JavaScript's `Number.prototype.toString`.
1491pub(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
1498/// `Number(n.toPrecision(15))` for non-integers, as `$string` does before printing a number.
1499pub(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
1506/// Compares strings like JavaScript's `<`, by UTF-16 code units.
1507pub(crate) fn js_string_cmp(a: &str, b: &str) -> Ordering {
1508    a.encode_utf16().cmp(b.encode_utf16())
1509}
1510
1511/// Writes `s` as a JSON string literal with `JSON.stringify` escaping.
1512pub(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
1532/// `JSON.stringify` with the replacer jsonata-js uses in `$string`: numbers are rounded to 15
1533/// significant digits, infinite numbers raise D1001, functions become `""`.
1534pub(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
1544/// The error of a string that would exceed the size limit of `limit` bytes.
1545pub(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
1552/// Writes the JSON text of a value, failing as soon as the text is longer than `limit` bytes:
1553/// a value that appears many times could otherwise make a text far too long to hold.
1554fn 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"); // NaN
1573            } 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}