Skip to main content

tabnas/
value.rs

1// Copyright (c) 2013-2026 Richard Rodger, MIT License
2
3use indexmap::IndexMap;
4use serde::{Deserialize, Deserializer, Serialize, Serializer};
5use std::fmt;
6use std::sync::Arc;
7
8#[derive(Debug, Clone, PartialEq)]
9pub struct Text {
10    pub quote: String,
11    pub string: String,
12}
13
14impl Serialize for Text {
15    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
16    where
17        S: Serializer,
18    {
19        serializer.serialize_str(&self.string)
20    }
21}
22
23impl<'de> Deserialize<'de> for Text {
24    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
25    where
26        D: Deserializer<'de>,
27    {
28        Ok(Self {
29            quote: String::new(),
30            string: String::deserialize(deserializer)?,
31        })
32    }
33}
34
35#[derive(Debug, Clone, PartialEq)]
36pub struct MapRef {
37    pub value: IndexMap<String, Value>,
38    pub implicit: bool,
39    pub meta: IndexMap<String, Value>,
40}
41
42impl Serialize for MapRef {
43    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
44    where
45        S: Serializer,
46    {
47        self.value.serialize(serializer)
48    }
49}
50
51impl<'de> Deserialize<'de> for MapRef {
52    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
53    where
54        D: Deserializer<'de>,
55    {
56        Ok(Self {
57            value: IndexMap::deserialize(deserializer)?,
58            implicit: false,
59            meta: IndexMap::new(),
60        })
61    }
62}
63
64#[derive(Debug, Clone, PartialEq)]
65pub struct ListRef {
66    pub value: Vec<Value>,
67    pub implicit: bool,
68    pub child: Option<Box<Value>>,
69    pub meta: IndexMap<String, Value>,
70}
71
72impl Serialize for ListRef {
73    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
74    where
75        S: Serializer,
76    {
77        self.value.serialize(serializer)
78    }
79}
80
81impl<'de> Deserialize<'de> for ListRef {
82    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
83    where
84        D: Deserializer<'de>,
85    {
86        Ok(Self {
87            value: Vec::deserialize(deserializer)?,
88            implicit: false,
89            child: None,
90            meta: IndexMap::new(),
91        })
92    }
93}
94
95#[derive(Debug, Clone, PartialEq, Serialize)]
96#[serde(untagged)]
97pub enum Value {
98    Undefined,
99    Null,
100    Bool(bool),
101    Number(f64),
102    String(String),
103    /// Shared, not owned. The engine builds a tree by folding each
104    /// finished rule's value into its parent's container, and with an
105    /// owned container that fold copied the whole accumulated subtree --
106    /// once per level, so a document nested `d` deep cost O(d^2). A
107    /// depth-1024 document took 398 ms where TypeScript, whose values are
108    /// references, took 6 ms. Behind an `Arc` the fold is a refcount bump
109    /// and the build is linear again.
110    ///
111    /// `Arc` rather than `Rc` because `Value` is `Send + Sync` and has to
112    /// stay that way: `Options` carries `Value`s and is shared as
113    /// `Arc<Options>`, and a parsed value can be sent between threads
114    /// today. The atomic lands only on containers, never on a `Number` or
115    /// a `String`, and one refcount beats copying a map by any measure.
116    ///
117    /// Mutate through `Arc::make_mut`, which copies only when the
118    /// container is genuinely shared.
119    Array(Arc<Vec<Value>>),
120    Object(Arc<IndexMap<String, Value>>),
121    Text(Text),
122    /// Shared for the reason above, and behind a pointer for the reason
123    /// they always were: a `ListRef` is 112 bytes and a `MapRef` 152, and
124    /// an unboxed variant sets the size of every `Value`, hence of every
125    /// `Token` and every `Rule`. Both are niche next to the scalars and
126    /// containers the parse loop moves constantly.
127    ListRef(Arc<ListRef>),
128    MapRef(Arc<MapRef>),
129}
130
131impl<'de> Deserialize<'de> for Value {
132    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
133    where
134        D: Deserializer<'de>,
135    {
136        // Undefined is an internal sentinel and has no distinct JSON
137        // representation. Deserialize through serde_json's tagged value so
138        // JSON null always becomes Value::Null instead of being captured by
139        // the first unit variant of an untagged enum.
140        serde_json::Value::deserialize(deserializer).map(|value| Self::from_json(&value))
141    }
142}
143
144/// Take a container out of its `Arc`, copying it only if it is shared.
145///
146/// `unwrap_undefined` consumes the value it is given, so the usual case
147/// is the last holder letting go and the contents moving out untouched.
148pub(crate) fn unwrap_arc<T: Clone>(shared: Arc<T>) -> T {
149    Arc::try_unwrap(shared).unwrap_or_else(|shared| (*shared).clone())
150}
151
152impl Value {
153    /// Build an array value from an owned vector.
154    ///
155    /// The variant holds an `Arc`, so that a value folded into a parent
156    /// container costs a refcount rather than a copy. Constructing one
157    /// still starts from an owned vector, and this is the shorthand for
158    /// handing it over.
159    pub fn array(values: Vec<Value>) -> Self {
160        Value::Array(Arc::new(values))
161    }
162
163    /// Build an object value from an owned map. See [`Value::array`].
164    pub fn object(entries: IndexMap<String, Value>) -> Self {
165        Value::Object(Arc::new(entries))
166    }
167
168    /// The array behind this value, ready to write to, or `None` when it
169    /// is not an array.
170    ///
171    /// Copies the contents first if anything else still shares them, so a
172    /// write through this handle is never seen by another holder. That
173    /// copy is the whole price of sharing, and it is paid only when a
174    /// value is mutated after being handed on -- which the tree build,
175    /// which only ever folds a finished value upwards, never does.
176    pub fn as_array_mut(&mut self) -> Option<&mut Vec<Value>> {
177        match self {
178            Value::Array(values) => Some(Arc::make_mut(values)),
179            _ => None,
180        }
181    }
182
183    /// The map behind this value, ready to write to, or `None` when it is
184    /// not an object. See [`Value::as_array_mut`].
185    pub fn as_object_mut(&mut self) -> Option<&mut IndexMap<String, Value>> {
186        match self {
187            Value::Object(entries) => Some(Arc::make_mut(entries)),
188            _ => None,
189        }
190    }
191
192    pub fn is_undefined(&self) -> bool {
193        matches!(self, Value::Undefined)
194    }
195
196    pub fn is_null(&self) -> bool {
197        matches!(self, Value::Null)
198    }
199
200    /// Replace every `Undefined` in the tree with `Null`.
201    ///
202    /// Iterative on purpose. The recursive form walked the document with
203    /// the call stack, one frame per nesting level, and a strict-JSON
204    /// parse of `[[[...]]]` overflowed the default 8 MiB main-thread stack
205    /// -- an uncatchable abort -- somewhere between 8,000 and 16,000
206    /// levels in a release build and between 2,000 and 4,000 in a debug
207    /// build. TypeScript's parse loop is iterative (`ts/src/parser.ts`,
208    /// `while (norule !== rule ...)`), so this walk was the only part of a
209    /// parse whose stack use grew with the document's depth.
210    /// `tests/deep_nesting_test.rs` pins it.
211    ///
212    /// The walk is also skipped when the tree holds no `Undefined`, the
213    /// common case: rebuilding every container would otherwise copy each
214    /// level, since the parse's root node still shares them.
215    pub fn unwrap_undefined(self) -> Value {
216        if !self.contains_undefined() {
217            return self;
218        }
219
220        let mut stack: Vec<UnwrapFrame> = Vec::new();
221        let mut result = match UnwrapFrame::open(self) {
222            Ok(frame) => {
223                stack.push(frame);
224                None
225            }
226            Err(leaf) => Some(leaf),
227        };
228        loop {
229            if let Some(value) = result.take() {
230                match stack.last_mut() {
231                    None => return value,
232                    Some(frame) => frame.done.push(value),
233                }
234            }
235            let frame = stack.last_mut().expect("an open container frame");
236            match frame.pending.next() {
237                Some(child) => match UnwrapFrame::open(child) {
238                    Ok(frame) => stack.push(frame),
239                    Err(leaf) => result = Some(leaf),
240                },
241                None => {
242                    let frame = stack.pop().expect("an open container frame");
243                    result = Some(frame.close());
244                }
245            }
246        }
247    }
248
249    /// Whether any `Undefined` sits anywhere in the tree. Iterative for
250    /// the same reason as [`Value::unwrap_undefined`].
251    fn contains_undefined(&self) -> bool {
252        let mut pending: Vec<&Value> = vec![self];
253        while let Some(value) = pending.pop() {
254            match value {
255                Value::Undefined => return true,
256                Value::Array(values) => pending.extend(values.iter()),
257                Value::Object(entries) => pending.extend(entries.values()),
258                Value::ListRef(list) => {
259                    pending.extend(list.value.iter());
260                    pending.extend(list.child.iter().map(|child| &**child));
261                    pending.extend(list.meta.values());
262                }
263                Value::MapRef(map) => {
264                    pending.extend(map.value.values());
265                    pending.extend(map.meta.values());
266                }
267                Value::Null
268                | Value::Bool(_)
269                | Value::Number(_)
270                | Value::String(_)
271                | Value::Text(_) => {}
272            }
273        }
274        false
275    }
276
277    pub fn to_json(&self) -> serde_json::Value {
278        match self {
279            Value::Undefined => serde_json::Value::Null,
280            Value::Null => serde_json::Value::Null,
281            Value::Bool(b) => serde_json::Value::Bool(*b),
282            Value::Number(n) => {
283                if let Some(num) = serde_json::Number::from_f64(*n) {
284                    serde_json::Value::Number(num)
285                } else {
286                    serde_json::Value::Null
287                }
288            }
289            Value::String(s) => serde_json::Value::String(s.clone()),
290            Value::Array(arr) => {
291                serde_json::Value::Array(arr.iter().map(|v| v.to_json()).collect())
292            }
293            Value::Object(obj) => {
294                let mut map = serde_json::Map::new();
295                for (k, v) in obj.iter() {
296                    map.insert(k.clone(), v.to_json());
297                }
298                serde_json::Value::Object(map)
299            }
300            Value::Text(text) => serde_json::Value::String(text.string.clone()),
301            Value::ListRef(list) => {
302                serde_json::Value::Array(list.value.iter().map(Value::to_json).collect())
303            }
304            Value::MapRef(map_ref) => {
305                let mut map = serde_json::Map::new();
306                for (key, value) in &map_ref.value {
307                    map.insert(key.clone(), value.to_json());
308                }
309                serde_json::Value::Object(map)
310            }
311        }
312    }
313
314    pub fn from_json(v: &serde_json::Value) -> Self {
315        match v {
316            serde_json::Value::Null => Value::Null,
317            serde_json::Value::Bool(b) => Value::Bool(*b),
318            serde_json::Value::Number(n) => Value::Number(n.as_f64().unwrap_or(0.0)),
319            serde_json::Value::String(s) => Value::String(s.clone()),
320            serde_json::Value::Array(arr) => {
321                Value::array(arr.iter().map(Value::from_json).collect())
322            }
323            serde_json::Value::Object(map) => {
324                let mut out = IndexMap::with_capacity(map.len());
325                for (k, val) in map {
326                    out.insert(k.clone(), Value::from_json(val));
327                }
328                Value::object(out)
329            }
330        }
331    }
332
333    pub fn deep_equal(&self, other: &Value) -> bool {
334        match (self, other) {
335            (Value::Undefined, Value::Undefined) => true,
336            (Value::Null, Value::Null) => true,
337            (Value::Bool(a), Value::Bool(b)) => a == b,
338            (Value::Number(a), Value::Number(b)) => {
339                if a.is_nan() && b.is_nan() {
340                    true
341                } else {
342                    a.to_bits() == b.to_bits()
343                }
344            }
345            (Value::String(a), Value::String(b)) => a == b,
346            (Value::Array(a), Value::Array(b)) => {
347                if a.len() != b.len() {
348                    return false;
349                }
350                for (x, y) in a.iter().zip(b.iter()) {
351                    if !x.deep_equal(y) {
352                        return false;
353                    }
354                }
355                true
356            }
357            (Value::Object(a), Value::Object(b)) => {
358                if a.len() != b.len() {
359                    return false;
360                }
361                for (k, va) in a.iter() {
362                    if let Some(vb) = b.get(k) {
363                        if !va.deep_equal(vb) {
364                            return false;
365                        }
366                    } else {
367                        return false;
368                    }
369                }
370                true
371            }
372            (Value::Text(a), Value::Text(b)) => a == b,
373            (Value::ListRef(a), Value::ListRef(b)) => a == b,
374            (Value::MapRef(a), Value::MapRef(b)) => a == b,
375            _ => false,
376        }
377    }
378}
379
380/// One container on the explicit stack of [`Value::unwrap_undefined`]: the
381/// children still to visit, the children already rewritten, and whatever
382/// is needed to put the container back together.
383struct UnwrapFrame {
384    pending: std::vec::IntoIter<Value>,
385    done: Vec<Value>,
386    shape: UnwrapShape,
387}
388
389enum UnwrapShape {
390    Array,
391    Object(Vec<String>),
392    /// Children are the `value` items, then the `child` when present, then
393    /// the `meta` values, in that order.
394    List {
395        list: ListRef,
396        values: usize,
397        child: bool,
398        meta: Vec<String>,
399    },
400    /// Children are the `value` entries, then the `meta` entries.
401    Map {
402        map: MapRef,
403        values: Vec<String>,
404        meta: Vec<String>,
405    },
406}
407
408impl UnwrapFrame {
409    /// Open a container, or return the rewritten scalar.
410    fn open(value: Value) -> Result<Self, Value> {
411        let (children, shape) = match value {
412            Value::Undefined => return Err(Value::Null),
413            Value::Array(values) => (unwrap_arc(values), UnwrapShape::Array),
414            Value::Object(entries) => {
415                let (keys, values): (Vec<_>, Vec<_>) = unwrap_arc(entries).into_iter().unzip();
416                (values, UnwrapShape::Object(keys))
417            }
418            Value::ListRef(list) => {
419                let mut list = unwrap_arc(list);
420                let mut children = std::mem::take(&mut list.value);
421                let values = children.len();
422                let child = list.child.take();
423                let has_child = child.is_some();
424                children.extend(child.map(|child| *child));
425                let (meta, meta_values): (Vec<_>, Vec<_>) =
426                    std::mem::take(&mut list.meta).into_iter().unzip();
427                children.extend(meta_values);
428                (
429                    children,
430                    UnwrapShape::List {
431                        list,
432                        values,
433                        child: has_child,
434                        meta,
435                    },
436                )
437            }
438            Value::MapRef(map) => {
439                let mut map = unwrap_arc(map);
440                let (values, mut children): (Vec<_>, Vec<_>) =
441                    std::mem::take(&mut map.value).into_iter().unzip();
442                let (meta, meta_values): (Vec<_>, Vec<_>) =
443                    std::mem::take(&mut map.meta).into_iter().unzip();
444                children.extend(meta_values);
445                (children, UnwrapShape::Map { map, values, meta })
446            }
447            other => return Err(other),
448        };
449        Ok(Self {
450            done: Vec::with_capacity(children.len()),
451            pending: children.into_iter(),
452            shape,
453        })
454    }
455
456    /// Reassemble the container from its rewritten children.
457    fn close(self) -> Value {
458        let mut done = self.done.into_iter();
459        match self.shape {
460            UnwrapShape::Array => Value::array(done.collect()),
461            UnwrapShape::Object(keys) => Value::object(keys.into_iter().zip(done).collect()),
462            UnwrapShape::List {
463                mut list,
464                values,
465                child,
466                meta,
467            } => {
468                list.value = done.by_ref().take(values).collect();
469                list.child = if child {
470                    done.next().map(Box::new)
471                } else {
472                    None
473                };
474                list.meta = meta.into_iter().zip(done).collect();
475                Value::ListRef(Arc::new(list))
476            }
477            UnwrapShape::Map {
478                mut map,
479                values,
480                meta,
481            } => {
482                map.value = values.into_iter().zip(done.by_ref()).collect();
483                map.meta = meta.into_iter().zip(done).collect();
484                Value::MapRef(Arc::new(map))
485            }
486        }
487    }
488}
489
490impl fmt::Display for Value {
491    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
492        match self {
493            Value::Undefined => write!(f, "undefined"),
494            Value::Null => write!(f, "null"),
495            Value::Bool(b) => write!(f, "{}", b),
496            Value::Number(n) => {
497                if n.fract() == 0.0 && !n.is_infinite() && !n.is_nan() {
498                    write!(f, "{:.0}", n)
499                } else {
500                    write!(f, "{}", n)
501                }
502            }
503            Value::String(s) => write!(f, "\"{}\"", s),
504            Value::Array(arr) => {
505                write!(f, "[")?;
506                for (i, v) in arr.iter().enumerate() {
507                    if i > 0 {
508                        write!(f, ",")?;
509                    }
510                    write!(f, "{}", v)?;
511                }
512                write!(f, "]")
513            }
514            Value::Object(obj) => {
515                write!(f, "{{")?;
516                for (i, (k, v)) in obj.iter().enumerate() {
517                    if i > 0 {
518                        write!(f, ",")?;
519                    }
520                    write!(f, "\"{}\":{}", k, v)?;
521                }
522                write!(f, "}}")
523            }
524            Value::Text(text) => write!(f, "\"{}\"", text.string),
525            Value::ListRef(list) => write!(f, "{}", Value::array(list.value.clone())),
526            Value::MapRef(map) => write!(f, "{}", Value::object(map.value.clone())),
527        }
528    }
529}