jaq_interpret/
val.rs

1//! JSON values with reference-counted sharing.
2
3use crate::box_iter::{box_once, BoxIter};
4use crate::error::{Error, Type};
5use alloc::string::{String, ToString};
6use alloc::{boxed::Box, rc::Rc, vec::Vec};
7use core::cmp::Ordering;
8use core::fmt::{self, Debug, Display};
9use core::ops::{Add, Div, Mul, Neg, Rem, Sub};
10#[cfg(feature = "hifijson")]
11use hifijson::{LexAlloc, Token};
12use jaq_syn::{path::Opt, MathOp};
13
14/// JSON value with sharing.
15///
16/// The speciality of this type is that numbers are distinguished into
17/// machine-sized integers and 64-bit floating-point numbers.
18/// This allows using integers to index arrays,
19/// while using floating-point numbers to do general math.
20///
21/// Operations on numbers follow a few principles:
22/// * The sum, difference, product, and remainder of two integers is integer.
23/// * Any other operation between two numbers yields a float.
24#[derive(Clone, Debug)]
25pub enum Val {
26    /// Null
27    Null,
28    /// Boolean
29    Bool(bool),
30    /// Integer
31    Int(isize),
32    /// Floating-point number
33    Float(f64),
34    /// Floating-point number or integer not fitting into `Int`
35    Num(Rc<String>),
36    /// String
37    Str(Rc<String>),
38    /// Array
39    Arr(Rc<Vec<Val>>),
40    /// Object
41    Obj(Rc<Map<Rc<String>, Val>>),
42}
43
44/// Order-preserving map
45type Map<K, V> = indexmap::IndexMap<K, V, ahash::RandomState>;
46
47/// A value result.
48pub type ValR = Result<Val, Error>;
49
50/// A stream of value results.
51pub type ValRs<'a> = BoxIter<'a, ValR>;
52
53// This might be included in the Rust standard library:
54// <https://github.com/rust-lang/rust/issues/93610>
55fn rc_unwrap_or_clone<T: Clone>(a: Rc<T>) -> T {
56    Rc::try_unwrap(a).unwrap_or_else(|a| (*a).clone())
57}
58
59pub type ValR2<V> = Result<V, Error<V>>;
60pub type ValR2s<'a, V> = BoxIter<'a, ValR2<V>>;
61
62// This makes `f64::from_str` accessible as intra-doc link.
63#[cfg(doc)]
64use core::str::FromStr;
65
66/// Values that can be processed by the interpreter.
67///
68/// Implement this trait if you want jaq to process your own type of values.
69pub trait ValT:
70    Clone
71    + Display
72    + From<bool>
73    + From<isize>
74    + From<String>
75    + FromIterator<Self>
76    + PartialEq
77    + PartialOrd
78    + Add<Output = ValR2<Self>>
79    + Sub<Output = ValR2<Self>>
80    + Mul<Output = ValR2<Self>>
81    + Div<Output = ValR2<Self>>
82    + Rem<Output = ValR2<Self>>
83    + Neg<Output = ValR2<Self>>
84{
85    /// Create a number from a string.
86    ///
87    /// The number should adhere to the format accepted by [`f64::from_str`].
88    fn from_num(n: &str) -> ValR2<Self>;
89
90    /// Create an associative map (or object) from a sequence of key-value pairs.
91    ///
92    /// This is used when creating values with the syntax `{k: v}`.
93    fn from_map<I: IntoIterator<Item = (Self, Self)>>(iter: I) -> ValR2<Self>;
94
95    /// Yield the children of a value.
96    ///
97    /// This is used by `.[]`.
98    fn values(self) -> Box<dyn Iterator<Item = ValR2<Self>>>;
99
100    /// Yield the child of a value at the given index.
101    ///
102    /// This is used by `.[k]`.
103    ///
104    /// If `v.index(k)` is `Ok(_)`, then it is contained in `v.values()`.
105    fn index(self, index: &Self) -> ValR2<Self>;
106
107    /// Yield a slice of the value with the given range.
108    ///
109    /// This is used by `.[s:e]`, `.[s:]`, and `.[:e]`.
110    fn range(self, range: Range<&Self>) -> ValR2<Self>;
111
112    /// Map a function over the children of the value.
113    ///
114    /// This is used by
115    /// - `.[]  |= f` (`opt` = [`Opt::Essential`]) and
116    /// - `.[]? |= f` (`opt` = [`Opt::Optional`]).
117    ///
118    /// If the children of the value are undefined, then:
119    ///
120    /// - If `opt` is [`Opt::Essential`], return an error.
121    /// - If `opt` is [`Opt::Optional`] , return the input value.
122    fn map_values<I: Iterator<Item = ValR2<Self>>>(
123        self,
124        opt: Opt,
125        f: impl Fn(Self) -> I,
126    ) -> ValR2<Self>;
127
128    /// Map a function over the child of the value at the given index.
129    ///
130    /// This is used by `.[k] |= f`.
131    ///
132    /// See [`Self::map_values`] for the behaviour of `opt`.
133    fn map_index<I: Iterator<Item = ValR2<Self>>>(
134        self,
135        index: &Self,
136        opt: Opt,
137        f: impl Fn(Self) -> I,
138    ) -> ValR2<Self>;
139
140    /// Map a function over the slice of the value with the given range.
141    ///
142    /// This is used by `.[s:e] |= f`, `.[s:] |= f`, and `.[:e] |= f`.
143    ///
144    /// See [`Self::map_values`] for the behaviour of `opt`.
145    fn map_range<I: Iterator<Item = ValR2<Self>>>(
146        self,
147        range: Range<&Self>,
148        opt: Opt,
149        f: impl Fn(Self) -> I,
150    ) -> ValR2<Self>;
151
152    /// Return a boolean representation of the value.
153    ///
154    /// This is used by `if v then ...`.
155    fn as_bool(&self) -> bool;
156
157    /// If the value is a string, return it.
158    ///
159    /// If `v.as_str()` yields `Some(s)`, then
160    /// `"\(v)"` yields `s`, otherwise it yields `v.to_string()`
161    /// (provided by [`Display`]).
162    fn as_str(&self) -> Option<&str>;
163}
164
165type Range<V> = core::ops::Range<Option<V>>;
166
167impl ValT for Val {
168    fn from_num(n: &str) -> ValR2<Self> {
169        Ok(Val::Num(Rc::new(n.to_string())))
170    }
171
172    fn from_map<I: IntoIterator<Item = (Self, Self)>>(iter: I) -> ValR2<Self> {
173        let iter = iter.into_iter().map(|(k, v)| Ok((k.to_str()?, v)));
174        Ok(Self::obj(iter.collect::<Result<_, _>>()?))
175    }
176
177    fn values(self) -> Box<dyn Iterator<Item = ValR2<Self>>> {
178        match self {
179            Self::Arr(a) => Box::new(rc_unwrap_or_clone(a).into_iter().map(Ok)),
180            Self::Obj(o) => Box::new(rc_unwrap_or_clone(o).into_iter().map(|(_k, v)| Ok(v))),
181            _ => box_once(Err(Error::Type(self, Type::Iter))),
182        }
183    }
184
185    fn index(self, index: &Self) -> ValR {
186        match (self, index) {
187            (Val::Arr(a), Val::Int(i)) => Ok(abs_index(*i, a.len())
188                .map(|i| a[i].clone())
189                .unwrap_or(Val::Null)),
190            (Val::Obj(o), Val::Str(s)) => Ok(o.get(s).cloned().unwrap_or(Val::Null)),
191            (s @ (Val::Arr(_) | Val::Obj(_)), _) => Err(Error::Index(s, index.clone())),
192            (s, _) => Err(Error::Type(s, Type::Iter)),
193        }
194    }
195
196    fn range(self, range: Range<&Self>) -> ValR {
197        let (from, upto) = (range.start, range.end);
198        match self {
199            Val::Arr(a) => {
200                let len = a.len();
201                let from = from.as_ref().map(|i| i.as_int()).transpose();
202                let upto = upto.as_ref().map(|i| i.as_int()).transpose();
203                from.and_then(|from| Ok((from, upto?))).map(|(from, upto)| {
204                    let from = abs_bound(from, len, 0);
205                    let upto = abs_bound(upto, len, len);
206                    let (skip, take) = skip_take(from, upto);
207                    a.iter().skip(skip).take(take).cloned().collect()
208                })
209            }
210            Val::Str(s) => {
211                let len = s.chars().count();
212                let from = from.as_ref().map(|i| i.as_int()).transpose();
213                let upto = upto.as_ref().map(|i| i.as_int()).transpose();
214                from.and_then(|from| Ok((from, upto?))).map(|(from, upto)| {
215                    let from = abs_bound(from, len, 0);
216                    let upto = abs_bound(upto, len, len);
217                    let (skip, take) = skip_take(from, upto);
218                    Val::from(s.chars().skip(skip).take(take).collect::<String>())
219                })
220            }
221            _ => Err(Error::Type(self, Type::Range)),
222        }
223    }
224
225    fn map_values<I: Iterator<Item = ValR>>(self, opt: Opt, f: impl Fn(Self) -> I) -> ValR {
226        match self {
227            Self::Arr(a) => {
228                let iter = rc_unwrap_or_clone(a).into_iter().flat_map(f);
229                Ok(iter.collect::<Result<_, _>>()?)
230            }
231            Self::Obj(o) => {
232                let iter = rc_unwrap_or_clone(o).into_iter();
233                let iter = iter.filter_map(|(k, v)| f(v).next().map(|v| Ok((k, v?))));
234                Ok(Self::obj(iter.collect::<Result<_, _>>()?))
235            }
236            v => opt.fail(v, |v| Error::Type(v, Type::Iter)),
237        }
238    }
239
240    fn map_index<I: Iterator<Item = ValR>>(
241        mut self,
242        index: &Self,
243        opt: Opt,
244        f: impl Fn(Self) -> I,
245    ) -> ValR {
246        match self {
247            Val::Obj(ref mut o) => {
248                let o = Rc::make_mut(o);
249                use indexmap::map::Entry::{Occupied, Vacant};
250                let i = match index {
251                    Val::Str(s) => s,
252                    i => return opt.fail(self, |v| Error::Index(v, i.clone())),
253                };
254                match o.entry(Rc::clone(i)) {
255                    Occupied(mut e) => {
256                        match f(e.get().clone()).next().transpose()? {
257                            Some(y) => e.insert(y),
258                            // this runs in constant time, at the price of
259                            // changing the order of the elements
260                            None => e.swap_remove(),
261                        };
262                    }
263                    Vacant(e) => {
264                        if let Some(y) = f(Val::Null).next().transpose()? {
265                            e.insert(y);
266                        }
267                    }
268                }
269                Ok(self)
270            }
271            Val::Arr(ref mut a) => {
272                let a = Rc::make_mut(a);
273                let abs_or = |i| abs_index(i, a.len()).ok_or(Error::IndexOutOfBounds(i));
274                let i = match index.as_int().and_then(abs_or) {
275                    Ok(i) => i,
276                    Err(e) => return opt.fail(self, |_| e),
277                };
278
279                if let Some(y) = f(a[i].clone()).next().transpose()? {
280                    a[i] = y;
281                } else {
282                    a.remove(i);
283                }
284                Ok(self)
285            }
286            _ => opt.fail(self, |v| Error::Type(v, Type::Iter)),
287        }
288    }
289
290    fn map_range<I: Iterator<Item = ValR>>(
291        mut self,
292        range: Range<&Self>,
293        opt: Opt,
294        f: impl Fn(Self) -> I,
295    ) -> ValR {
296        if let Val::Arr(ref mut a) = self {
297            let a = Rc::make_mut(a);
298            let from = range.start.as_ref().map(|i| i.as_int()).transpose();
299            let upto = range.end.as_ref().map(|i| i.as_int()).transpose();
300            let (from, upto) = match from.and_then(|from| Ok((from, upto?))) {
301                Ok(from_upto) => from_upto,
302                Err(e) => return opt.fail(self, |_| e),
303            };
304            let len = a.len();
305            let from = abs_bound(from, len, 0);
306            let upto = abs_bound(upto, len, len);
307            let (skip, take) = skip_take(from, upto);
308            let arr = Val::arr(a.iter().skip(skip).take(take).cloned().collect());
309            let y = f(arr).map(|y| y?.into_arr()).next().transpose()?;
310            a.splice(skip..skip + take, (*y.unwrap_or_default()).clone());
311            Ok(self)
312        } else {
313            opt.fail(self, |v| Error::Type(v, Type::Arr))
314        }
315    }
316
317    fn as_bool(&self) -> bool {
318        self.as_bool()
319    }
320
321    /// If the value is a string, return it, else fail.
322    fn as_str(&self) -> Option<&str> {
323        if let Self::Str(s) = self {
324            Some(s)
325        } else {
326            None
327        }
328    }
329}
330
331fn skip_take(from: usize, until: usize) -> (usize, usize) {
332    (from, if until > from { until - from } else { 0 })
333}
334
335/// If a range bound is given, absolutise and clip it between 0 and `len`,
336/// else return `default`.
337fn abs_bound(i: Option<isize>, len: usize, default: usize) -> usize {
338    let abs = |i| core::cmp::min(wrap(i, len).unwrap_or(0), len);
339    i.map(abs).unwrap_or(default)
340}
341
342/// Absolutise an index and return result if it is inside [0, len).
343fn abs_index(i: isize, len: usize) -> Option<usize> {
344    wrap(i, len).filter(|i| *i < len)
345}
346
347fn wrap(i: isize, len: usize) -> Option<usize> {
348    if i >= 0 {
349        Some(i as usize)
350    } else if len < -i as usize {
351        None
352    } else {
353        Some(len - (-i as usize))
354    }
355}
356
357#[test]
358fn wrap_test() {
359    let len = 4;
360    assert_eq!(wrap(0, len), Some(0));
361    assert_eq!(wrap(8, len), Some(8));
362    assert_eq!(wrap(-1, len), Some(3));
363    assert_eq!(wrap(-4, len), Some(0));
364    assert_eq!(wrap(-8, len), None);
365}
366
367impl Val {
368    /// Construct a string value.
369    pub fn str(s: String) -> Self {
370        Self::Str(s.into())
371    }
372
373    /// Construct an array value.
374    pub fn arr(v: Vec<Self>) -> Self {
375        Self::Arr(v.into())
376    }
377
378    /// Construct an object value.
379    pub fn obj(m: Map<Rc<String>, Self>) -> Self {
380        Self::Obj(m.into())
381    }
382
383    /// True if the value is neither null nor false.
384    pub fn as_bool(&self) -> bool {
385        !matches!(self, Self::Null | Self::Bool(false))
386    }
387
388    /// If the value is integer, return it, else fail.
389    pub fn as_int(&self) -> Result<isize, Error> {
390        match self {
391            Self::Int(i) => Ok(*i),
392            _ => Err(Error::Type(self.clone(), Type::Int)),
393        }
394    }
395
396    /// If the value is or can be converted to float, return it, else
397    /// fail.
398    pub fn as_float(&self) -> Result<f64, Error> {
399        match self {
400            Self::Int(n) => Ok(*n as f64),
401            Self::Float(n) => Ok(*n),
402            Self::Num(n) => n.parse().or(Err(Error::Type(self.clone(), Type::Float))),
403            _ => Err(Error::Type(self.clone(), Type::Float)),
404        }
405    }
406
407    /// If the value is a string, return it, else fail.
408    pub fn to_str(self) -> Result<Rc<String>, Error> {
409        match self {
410            Self::Str(s) => Ok(s),
411            _ => Err(Error::Type(self, Type::Str)),
412        }
413    }
414
415    /// If the value is a string, return it, else fail.
416    pub fn as_str(&self) -> Result<&Rc<String>, Error> {
417        match self {
418            Self::Str(s) => Ok(s),
419            _ => Err(Error::Type(self.clone(), Type::Str)),
420        }
421    }
422
423    /// If the value is a Str, extract the inner string, else convert
424    /// it to string.
425    pub fn to_string_or_clone(&self) -> String {
426        match self {
427            Self::Str(s) => (**s).clone(),
428            _ => self.to_string(),
429        }
430    }
431
432    /// If the value is an array, return it, else fail.
433    pub fn into_arr(self) -> Result<Rc<Vec<Self>>, Error> {
434        match self {
435            Self::Arr(a) => Ok(a),
436            _ => Err(Error::Type(self, Type::Arr)),
437        }
438    }
439
440    /// If the value is an array, return it, else fail.
441    pub fn as_arr(&self) -> Result<&Rc<Vec<Self>>, Error> {
442        match self {
443            Self::Arr(a) => Ok(a),
444            _ => Err(Error::Type(self.clone(), Type::Arr)),
445        }
446    }
447
448    /// Try to parse a string to a [`Self::Float`], else return [`Self::Null`].
449    pub fn from_dec_str(n: &str) -> Self {
450        n.parse().map_or(Self::Null, Self::Float)
451    }
452
453    /// Apply a rounding function to floating-point numbers, then convert them to integers.
454    ///
455    /// Return integers unchanged, and fail on any other input.
456    pub fn round(&self, f: impl FnOnce(f64) -> f64) -> Result<Self, Error> {
457        match self {
458            Self::Int(_) => Ok(self.clone()),
459            // TODO: this should fail if float does not fit into isize!
460            Self::Float(x) => Ok(Self::Int(f(*x) as isize)),
461            Self::Num(n) => Self::from_dec_str(n).round(f),
462            _ => Err(Error::Type(self.clone(), Type::Num)),
463        }
464    }
465
466    /// Return true if `value | .[key]` is defined.
467    ///
468    /// Fail on values that are neither arrays nor objects.
469    pub fn has(&self, key: &Self) -> Result<bool, Error> {
470        match (self, key) {
471            (Self::Arr(a), Self::Int(i)) if *i >= 0 => Ok((*i as usize) < a.len()),
472            (Self::Obj(o), Self::Str(s)) => Ok(o.contains_key(&**s)),
473            _ => Err(Error::Index(self.clone(), key.clone())),
474        }
475    }
476
477    /// Return any `key` for which `value | .[key]` is defined.
478    ///
479    /// Fail on values that are neither arrays nor objects.
480    pub fn keys_unsorted(&self) -> Result<Vec<Self>, Error> {
481        match self {
482            Self::Arr(a) => Ok((0..a.len() as isize).map(Self::Int).collect()),
483            Self::Obj(o) => Ok(o.keys().map(|k| Self::Str(Rc::clone(k))).collect()),
484            _ => Err(Error::Type(self.clone(), Type::Iter)),
485        }
486    }
487
488    /// Return the elements of an array or the values of an object (omitting its keys).
489    ///
490    /// Fail on any other value.
491    #[deprecated(since = "1.3.0", note = "use `ValT::values` instead")]
492    pub fn try_into_iter(self) -> Result<Box<dyn Iterator<Item = Self>>, Error> {
493        match self {
494            Self::Arr(a) => Ok(Box::new(rc_unwrap_or_clone(a).into_iter())),
495            Self::Obj(o) => Ok(Box::new(rc_unwrap_or_clone(o).into_iter().map(|(_k, v)| v))),
496            _ => Err(Error::Type(self, Type::Iter)),
497        }
498    }
499
500    /// `a` contains `b` iff either
501    /// * the string `b` is a substring of `a`,
502    /// * every element in the array `b` is contained in some element of the array `a`,
503    /// * for every key-value pair `k, v` in `b`,
504    ///   there is a key-value pair `k, v'` in `a` such that `v'` contains `v`, or
505    /// * `a` equals `b`.
506    pub fn contains(&self, other: &Self) -> bool {
507        match (self, other) {
508            (Self::Str(l), Self::Str(r)) => l.contains(&**r),
509            (Self::Arr(l), Self::Arr(r)) => r.iter().all(|r| l.iter().any(|l| l.contains(r))),
510            (Self::Obj(l), Self::Obj(r)) => r
511                .iter()
512                .all(|(k, r)| l.get(k).map(|l| l.contains(r)).unwrap_or(false)),
513            _ => self == other,
514        }
515    }
516
517    /// Apply a function to a string.
518    pub fn mutate_str(self, f: impl Fn(&mut String)) -> ValR {
519        let mut s = self.to_str()?;
520        f(Rc::make_mut(&mut s));
521        Ok(Self::Str(s))
522    }
523
524    /// Apply a function to an array.
525    pub fn mutate_arr(self, f: impl Fn(&mut Vec<Self>)) -> ValR {
526        let mut a = self.into_arr()?;
527        f(Rc::make_mut(&mut a));
528        Ok(Self::Arr(a))
529    }
530
531    /// Apply a fallible function to an array.
532    pub fn try_mutate_arr(self, f: impl Fn(&mut Vec<Self>) -> Result<(), Error>) -> ValR {
533        let mut a = self.into_arr()?;
534        f(Rc::make_mut(&mut a))?;
535        Ok(Self::Arr(a))
536    }
537
538    /// Parse at least one JSON value, given an initial token and a lexer.
539    ///
540    /// If the underlying lexer reads input fallibly (for example `IterLexer`),
541    /// the error returned by this function might be misleading.
542    /// In that case, always check whether the lexer contains an error.
543    #[cfg(feature = "hifijson")]
544    pub fn parse(token: Token, lexer: &mut impl LexAlloc) -> Result<Self, hifijson::Error> {
545        use hifijson::{token, Error};
546        match token {
547            Token::Null => Ok(Self::Null),
548            Token::True => Ok(Self::Bool(true)),
549            Token::False => Ok(Self::Bool(false)),
550            Token::DigitOrMinus => {
551                let (num, parts) = lexer.num_string()?;
552                // if we are dealing with an integer ...
553                if parts.dot.is_none() && parts.exp.is_none() {
554                    // ... that fits into an isize
555                    if let Ok(i) = num.parse() {
556                        return Ok(Self::Int(i));
557                    }
558                }
559                Ok(Self::Num(Rc::new(num.to_string())))
560            }
561            Token::Quote => Ok(Self::str(lexer.str_string()?.to_string())),
562            Token::LSquare => Ok(Self::arr({
563                let mut arr = Vec::new();
564                lexer.seq(Token::RSquare, |token, lexer| {
565                    arr.push(Self::parse(token, lexer)?);
566                    Ok::<_, hifijson::Error>(())
567                })?;
568                arr
569            })),
570            Token::LCurly => Ok(Self::obj({
571                let mut obj: Map<_, _> = Default::default();
572                lexer.seq(Token::RCurly, |token, lexer| {
573                    let key =
574                        lexer.str_colon(token, |lexer| lexer.str_string().map_err(Error::Str))?;
575
576                    let token = lexer.ws_token().ok_or(token::Expect::Value)?;
577                    let value = Self::parse(token, lexer)?;
578                    obj.insert(Rc::new(key.to_string()), value);
579                    Ok::<_, Error>(())
580                })?;
581                obj
582            })),
583            _ => Err(token::Expect::Value)?,
584        }
585    }
586}
587
588#[cfg(feature = "serde_json")]
589impl From<serde_json::Value> for Val {
590    fn from(v: serde_json::Value) -> Self {
591        use serde_json::Value::*;
592        match v {
593            Null => Self::Null,
594            Bool(b) => Self::Bool(b),
595            Number(n) => n
596                .to_string()
597                .parse()
598                .map_or_else(|_| Self::Num(Rc::new(n.to_string())), Self::Int),
599            String(s) => Self::str(s),
600            Array(a) => Self::arr(a.into_iter().map(|x| x.into()).collect()),
601            Object(o) => Self::obj(o.into_iter().map(|(k, v)| (Rc::new(k), v.into())).collect()),
602        }
603    }
604}
605
606#[cfg(feature = "serde_json")]
607impl From<Val> for serde_json::Value {
608    fn from(v: Val) -> Self {
609        use core::str::FromStr;
610        use serde_json::Value::*;
611        match v {
612            Val::Null => Null,
613            Val::Bool(b) => Bool(b),
614            Val::Int(i) => Number(i.into()),
615            Val::Float(f) => serde_json::Number::from_f64(f).map_or(Null, Number),
616            Val::Num(n) => Number(serde_json::Number::from_str(&n).unwrap()),
617            Val::Str(s) => String((*s).clone()),
618            Val::Arr(a) => Array(a.iter().map(|x| x.clone().into()).collect()),
619            Val::Obj(o) => Object(
620                o.iter()
621                    .map(|(k, v)| ((**k).clone(), v.clone().into()))
622                    .collect(),
623            ),
624        }
625    }
626}
627
628impl From<bool> for Val {
629    fn from(b: bool) -> Self {
630        Self::Bool(b)
631    }
632}
633
634impl From<isize> for Val {
635    fn from(i: isize) -> Self {
636        Self::Int(i)
637    }
638}
639
640impl From<f64> for Val {
641    fn from(f: f64) -> Self {
642        Self::Float(f)
643    }
644}
645
646impl From<String> for Val {
647    fn from(s: String) -> Self {
648        Self::Str(Rc::new(s))
649    }
650}
651
652impl FromIterator<Self> for Val {
653    fn from_iter<T: IntoIterator<Item = Self>>(iter: T) -> Self {
654        Self::Arr(Rc::new(iter.into_iter().collect()))
655    }
656}
657
658impl core::ops::Add for Val {
659    type Output = ValR;
660    fn add(self, rhs: Self) -> Self::Output {
661        use Val::*;
662        match (self, rhs) {
663            // `null` is a neutral element for addition
664            (Null, x) | (x, Null) => Ok(x),
665            (Int(x), Int(y)) => Ok(Int(x + y)),
666            (Int(i), Float(f)) | (Float(f), Int(i)) => Ok(Float(f + i as f64)),
667            (Float(x), Float(y)) => Ok(Float(x + y)),
668            (Num(n), r) => Self::from_dec_str(&n) + r,
669            (l, Num(n)) => l + Self::from_dec_str(&n),
670            (Str(mut l), Str(r)) => {
671                Rc::make_mut(&mut l).push_str(&r);
672                Ok(Str(l))
673            }
674            (Arr(mut l), Arr(r)) => {
675                //std::dbg!(Rc::strong_count(&l));
676                Rc::make_mut(&mut l).extend(r.iter().cloned());
677                Ok(Arr(l))
678            }
679            (Obj(mut l), Obj(r)) => {
680                Rc::make_mut(&mut l).extend(r.iter().map(|(k, v)| (k.clone(), v.clone())));
681                Ok(Obj(l))
682            }
683            (l, r) => Err(Error::MathOp(l, MathOp::Add, r)),
684        }
685    }
686}
687
688impl core::ops::Sub for Val {
689    type Output = ValR;
690    fn sub(self, rhs: Self) -> Self::Output {
691        use Val::*;
692        match (self, rhs) {
693            (Int(x), Int(y)) => Ok(Int(x - y)),
694            (Float(f), Int(i)) => Ok(Float(f - i as f64)),
695            (Int(i), Float(f)) => Ok(Float(i as f64 - f)),
696            (Float(x), Float(y)) => Ok(Float(x - y)),
697            (Num(n), r) => Self::from_dec_str(&n) - r,
698            (l, Num(n)) => l - Self::from_dec_str(&n),
699            (Arr(mut l), Arr(r)) => {
700                let r = alloc::collections::BTreeSet::from_iter(r.iter());
701                Rc::make_mut(&mut l).retain(|x| !r.contains(x));
702                Ok(Arr(l))
703            }
704            (l, r) => Err(Error::MathOp(l, MathOp::Sub, r)),
705        }
706    }
707}
708
709fn obj_merge(l: &mut Rc<Map<Rc<String>, Val>>, r: Rc<Map<Rc<String>, Val>>) {
710    let l = Rc::make_mut(l);
711    let r = rc_unwrap_or_clone(r).into_iter();
712    r.for_each(|(k, v)| match (l.get_mut(&k), v) {
713        (Some(Val::Obj(l)), Val::Obj(r)) => obj_merge(l, r),
714        (Some(l), r) => *l = r,
715        (None, r) => {
716            l.insert(k, r);
717        }
718    })
719}
720
721impl core::ops::Mul for Val {
722    type Output = ValR;
723    fn mul(self, rhs: Self) -> Self::Output {
724        use Val::*;
725        match (self, rhs) {
726            (Int(x), Int(y)) => Ok(Int(x * y)),
727            (Float(f), Int(i)) | (Int(i), Float(f)) => Ok(Float(f * i as f64)),
728            (Float(x), Float(y)) => Ok(Float(x * y)),
729            (Str(s), Int(i)) | (Int(i), Str(s)) if i > 0 => Ok(Self::str(s.repeat(i as usize))),
730            // string multiplication with negatives or 0 results in null
731            // <https://jqlang.github.io/jq/manual/#Builtinoperatorsandfunctions>
732            (Str(_), Int(_)) | (Int(_), Str(_)) => Ok(Null),
733            (Num(n), r) => Self::from_dec_str(&n) * r,
734            (l, Num(n)) => l * Self::from_dec_str(&n),
735            (Obj(mut l), Obj(r)) => {
736                obj_merge(&mut l, r);
737                Ok(Obj(l))
738            }
739            (l, r) => Err(Error::MathOp(l, MathOp::Mul, r)),
740        }
741    }
742}
743
744/// Split a string by a given separator string.
745fn split<'a>(s: &'a str, sep: &'a str) -> BoxIter<'a, String> {
746    if s.is_empty() {
747        Box::new(core::iter::empty())
748    } else if sep.is_empty() {
749        // Rust's `split` function with an empty separator ("")
750        // yields an empty string as first and last result
751        // to prevent this, we are using `chars` instead
752        Box::new(s.chars().map(|s| s.to_string()))
753    } else {
754        Box::new(s.split(sep).map(|s| s.to_string()))
755    }
756}
757
758impl core::ops::Div for Val {
759    type Output = ValR;
760    fn div(self, rhs: Self) -> Self::Output {
761        use Val::*;
762        match (self, rhs) {
763            (Int(x), Int(y)) => Ok(Float(x as f64 / y as f64)),
764            (Float(f), Int(i)) => Ok(Float(f / i as f64)),
765            (Int(i), Float(f)) => Ok(Float(i as f64 / f)),
766            (Float(x), Float(y)) => Ok(Float(x / y)),
767            (Num(n), r) => Self::from_dec_str(&n) / r,
768            (l, Num(n)) => l / Self::from_dec_str(&n),
769            (Str(x), Str(y)) => Ok(Val::arr(split(&x, &y).map(Val::str).collect())),
770            (l, r) => Err(Error::MathOp(l, MathOp::Div, r)),
771        }
772    }
773}
774
775impl core::ops::Rem for Val {
776    type Output = ValR;
777    fn rem(self, rhs: Self) -> Self::Output {
778        use Val::*;
779        match (self, rhs) {
780            (Int(x), Int(y)) if y != 0 => Ok(Int(x % y)),
781            (l, r) => Err(Error::MathOp(l, MathOp::Rem, r)),
782        }
783    }
784}
785
786impl core::ops::Neg for Val {
787    type Output = ValR;
788    fn neg(self) -> Self::Output {
789        use Val::*;
790        match self {
791            Int(x) => Ok(Int(-x)),
792            Float(x) => Ok(Float(-x)),
793            Num(n) => -Self::from_dec_str(&n),
794            x => Err(Error::Type(x, Type::Num)),
795        }
796    }
797}
798
799impl PartialEq for Val {
800    fn eq(&self, other: &Self) -> bool {
801        match (self, other) {
802            (Self::Null, Self::Null) => true,
803            (Self::Bool(x), Self::Bool(y)) => x == y,
804            (Self::Int(x), Self::Int(y)) => x == y,
805            (Self::Int(i), Self::Float(f)) | (Self::Float(f), Self::Int(i)) => {
806                float_eq(*i as f64, *f)
807            }
808            (Self::Float(x), Self::Float(y)) => float_eq(*x, *y),
809            (Self::Num(x), Self::Num(y)) if Rc::ptr_eq(x, y) => true,
810            (Self::Num(n), y) => &Self::from_dec_str(n) == y,
811            (x, Self::Num(n)) => x == &Self::from_dec_str(n),
812            (Self::Str(x), Self::Str(y)) => x == y,
813            (Self::Arr(x), Self::Arr(y)) => x == y,
814            (Self::Obj(x), Self::Obj(y)) => x == y,
815            _ => false,
816        }
817    }
818}
819
820impl Eq for Val {}
821
822impl PartialOrd for Val {
823    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
824        Some(self.cmp(other))
825    }
826}
827
828impl Ord for Val {
829    fn cmp(&self, other: &Self) -> Ordering {
830        use Ordering::*;
831        match (self, other) {
832            (Self::Null, Self::Null) => Equal,
833            (Self::Bool(x), Self::Bool(y)) => x.cmp(y),
834            (Self::Int(x), Self::Int(y)) => x.cmp(y),
835            (Self::Int(i), Self::Float(f)) => float_cmp(*i as f64, *f),
836            (Self::Float(f), Self::Int(i)) => float_cmp(*f, *i as f64),
837            (Self::Float(x), Self::Float(y)) => float_cmp(*x, *y),
838            (Self::Num(x), Self::Num(y)) if Rc::ptr_eq(x, y) => Equal,
839            (Self::Num(n), y) => Self::from_dec_str(n).cmp(y),
840            (x, Self::Num(n)) => x.cmp(&Self::from_dec_str(n)),
841            (Self::Str(x), Self::Str(y)) => x.cmp(y),
842            (Self::Arr(x), Self::Arr(y)) => x.cmp(y),
843            (Self::Obj(x), Self::Obj(y)) => match (x.len(), y.len()) {
844                (0, 0) => Equal,
845                (0, _) => Less,
846                (_, 0) => Greater,
847                _ => {
848                    let mut l: Vec<_> = x.iter().collect();
849                    let mut r: Vec<_> = y.iter().collect();
850                    l.sort_by_key(|(k, _v)| *k);
851                    r.sort_by_key(|(k, _v)| *k);
852                    // TODO: make this nicer
853                    let kl = l.iter().map(|(k, _v)| k);
854                    let kr = r.iter().map(|(k, _v)| k);
855                    let vl = l.iter().map(|(_k, v)| v);
856                    let vr = r.iter().map(|(_k, v)| v);
857                    kl.cmp(kr).then_with(|| vl.cmp(vr))
858                }
859            },
860
861            // nulls are smaller than anything else
862            (Self::Null, _) => Less,
863            (_, Self::Null) => Greater,
864            // bools are smaller than anything else, except for nulls
865            (Self::Bool(_), _) => Less,
866            (_, Self::Bool(_)) => Greater,
867            // numbers are smaller than anything else, except for nulls and bools
868            (Self::Int(_) | Self::Float(_), _) => Less,
869            (_, Self::Int(_) | Self::Float(_)) => Greater,
870            // etc.
871            (Self::Str(_), _) => Less,
872            (_, Self::Str(_)) => Greater,
873            (Self::Arr(_), _) => Less,
874            (_, Self::Arr(_)) => Greater,
875        }
876    }
877}
878
879fn float_eq(left: f64, right: f64) -> bool {
880    float_cmp(left, right) == Ordering::Equal
881}
882
883fn float_cmp(left: f64, right: f64) -> Ordering {
884    if left == 0. && right == 0. {
885        Ordering::Equal
886    } else {
887        f64::total_cmp(&left, &right)
888    }
889}
890
891impl fmt::Display for Val {
892    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
893        match self {
894            Self::Null => write!(f, "null"),
895            Self::Bool(b) => write!(f, "{b}"),
896            Self::Int(i) => write!(f, "{i}"),
897            Self::Float(x) if x.is_finite() => write!(f, "{x:?}"),
898            Self::Float(_) => write!(f, "null"),
899            Self::Num(n) => write!(f, "{n}"),
900            Self::Str(s) => write!(f, "{s:?}"),
901            Self::Arr(a) => {
902                write!(f, "[")?;
903                let mut iter = a.iter();
904                if let Some(first) = iter.next() {
905                    write!(f, "{first}")?;
906                };
907                iter.try_for_each(|x| write!(f, ",{x}"))?;
908                write!(f, "]")
909            }
910            Self::Obj(o) => {
911                write!(f, "{{")?;
912                let mut iter = o.iter();
913                if let Some((k, v)) = iter.next() {
914                    write!(f, "{k:?}:{v}")?;
915                }
916                iter.try_for_each(|(k, v)| write!(f, ",{k:?}:{v}"))?;
917                write!(f, "}}")
918            }
919        }
920    }
921}