jaq_json/
lib.rs

1//! JSON superset with binary data and non-string object keys.
2//!
3//! This crate provides a few macros for formatting / writing;
4//! this is done in order to function with both
5//! [`core::fmt::Write`] and [`std::io::Write`].
6#![no_std]
7#![forbid(unsafe_code)]
8#![warn(missing_docs)]
9
10extern crate alloc;
11extern crate std;
12
13#[cfg(feature = "formats")]
14mod formats;
15mod funs;
16mod num;
17#[macro_use]
18mod write;
19
20#[cfg(feature = "cbor")]
21pub mod cbor;
22#[cfg(feature = "json")]
23pub mod json;
24#[cfg(feature = "toml")]
25pub mod toml;
26#[cfg(feature = "xml")]
27pub mod xml;
28#[cfg(feature = "yaml")]
29pub mod yaml;
30
31#[cfg(feature = "serde_json")]
32mod serde_json;
33
34use alloc::{borrow::ToOwned, boxed::Box, string::String, vec::Vec};
35use bstr::{BStr, ByteSlice};
36use bytes::{BufMut, Bytes, BytesMut};
37use core::cmp::Ordering;
38use core::fmt;
39use core::hash::{Hash, Hasher};
40use jaq_core::box_iter::box_once;
41use jaq_core::{load, ops, path, val, Exn};
42use num_bigint::BigInt;
43use num_traits::{cast::ToPrimitive, Signed};
44
45pub use funs::base_funs;
46#[cfg(feature = "formats")]
47pub use funs::funs;
48pub use num::Num;
49
50#[cfg(not(feature = "sync"))]
51pub use alloc::rc::Rc;
52#[cfg(feature = "sync")]
53pub use alloc::sync::Arc as Rc;
54
55/// JSON superset with binary data and non-string object keys.
56///
57/// This is the default value type for jaq.
58#[derive(Clone, Debug, Default)]
59pub enum Val {
60    #[default]
61    /// Null
62    Null,
63    /// Boolean
64    Bool(bool),
65    /// Number
66    Num(Num),
67    /// String
68    Str(Bytes, Tag),
69    /// Array
70    Arr(Rc<Vec<Val>>),
71    /// Object
72    Obj(Rc<Map<Val, Val>>),
73}
74
75#[cfg(feature = "sync")]
76#[test]
77fn val_send_sync() {
78    fn send_sync<T: Send + Sync>(_: T) {}
79    send_sync(Val::default())
80}
81
82/// Interpretation of a string.
83///
84/// This influences the outcome of a few operations (e.g. slicing)
85/// as well as how a string is printed.
86#[derive(Copy, Clone, Debug, PartialEq, Eq)]
87pub enum Tag {
88    /// Sequence of bytes, to be escaped
89    Bytes,
90    /// Sequence of UTF-8 code points
91    ///
92    /// Note that this does not require the actual bytes to be all valid UTF-8;
93    /// this just means that the bytes are interpreted as UTF-8.
94    /// An effort is made to preserve invalid UTF-8 as is, else
95    /// replace invalid UTF-8 by the Unicode replacement character.
96    Utf8,
97}
98
99/// Types and sets of types.
100#[derive(Clone, Debug, PartialEq, Eq)]
101enum Type {
102    /// `[] | .["a"]` or `limit("a"; 0)` or `range(0; "a")`
103    Int,
104    /*
105    /// `"1" | sin` or `pow(2; "3")` or `fma(2; 3; "4")`
106    Float,
107    */
108    /// `-"a"`, `"a" | round`
109    Num,
110    /*
111    /// `{(0): 1}` or `0 | fromjson` or `0 | explode` or `"a b c" | split(0)`
112    Str,
113    */
114    /// `0 | sort` or `0 | implode` or `[] | .[0:] = 0`
115    Arr,
116    /// `0 | .[]` or `0 | .[0]` or `0 | keys` (array or object)
117    Iter,
118    /// `{}[0:1]` (string or array)
119    Range,
120}
121
122impl Type {
123    fn as_str(&self) -> &'static str {
124        match self {
125            Self::Int => "integer",
126            //Self::Float => "floating-point number",
127            Self::Num => "number",
128            //Self::Str => "string",
129            Self::Arr => "array",
130            Self::Iter => "iterable (array or object)",
131            Self::Range => "rangeable (array or string)",
132        }
133    }
134}
135
136/// Order-preserving map
137pub type Map<K = Val, V = K> = indexmap::IndexMap<K, V, foldhash::fast::RandomState>;
138
139/// Error that can occur during filter execution.
140pub type Error = jaq_core::Error<Val>;
141/// A value or an eRror.
142pub type ValR = jaq_core::ValR<Val>;
143/// A value or an eXception.
144pub type ValX = jaq_core::ValX<Val>;
145
146// This is part of the Rust standard library since 1.76:
147// <https://doc.rust-lang.org/std/rc/struct.Rc.html#method.unwrap_or_clone>.
148// However, to keep MSRV low, we reimplement it here.
149fn rc_unwrap_or_clone<T: Clone>(a: Rc<T>) -> T {
150    Rc::try_unwrap(a).unwrap_or_else(|a| (*a).clone())
151}
152
153impl jaq_core::ValT for Val {
154    fn from_num(n: &str) -> ValR {
155        Ok(Self::Num(Num::from_str(n)))
156    }
157
158    fn from_map<I: IntoIterator<Item = (Self, Self)>>(iter: I) -> ValR {
159        Ok(Self::obj(iter.into_iter().collect()))
160    }
161
162    fn key_values(self) -> Box<dyn Iterator<Item = Result<(Val, Val), Error>>> {
163        let arr_idx = |(i, x)| Ok((Self::from(i as isize), x));
164        match self {
165            Self::Arr(a) => Box::new(rc_unwrap_or_clone(a).into_iter().enumerate().map(arr_idx)),
166            Self::Obj(o) => Box::new(rc_unwrap_or_clone(o).into_iter().map(Ok)),
167            _ => box_once(Err(Error::typ(self, Type::Iter.as_str()))),
168        }
169    }
170
171    fn values(self) -> Box<dyn Iterator<Item = ValR>> {
172        match self {
173            Self::Arr(a) => Box::new(rc_unwrap_or_clone(a).into_iter().map(Ok)),
174            Self::Obj(o) => Box::new(rc_unwrap_or_clone(o).into_iter().map(|(_k, v)| Ok(v))),
175            _ => box_once(Err(Error::typ(self, Type::Iter.as_str()))),
176        }
177    }
178
179    fn index(self, index: &Self) -> ValR {
180        match (self, index) {
181            (Val::Null, _) => Ok(Val::Null),
182            (Val::Str(a, Tag::Bytes), Val::Num(i @ (Num::Int(_) | Num::BigInt(_)))) => Ok(i
183                .as_pos_usize()
184                .and_then(|i| abs_index(i, a.len()))
185                .map_or(Val::Null, |i| Val::from(a[i] as usize))),
186            (Val::Arr(a), Val::Num(i @ (Num::Int(_) | Num::BigInt(_)))) => Ok(i
187                .as_pos_usize()
188                .and_then(|i| abs_index(i, a.len()))
189                .map_or(Val::Null, |i| a[i].clone())),
190            (Val::Obj(o), i) => Ok(o.get(i).cloned().unwrap_or(Val::Null)),
191            (s @ (Val::Str(_, Tag::Bytes) | Val::Arr(_)), _) => Err(Error::index(s, index.clone())),
192            (s, _) => Err(Error::typ(s, Type::Iter.as_str())),
193        }
194    }
195
196    fn range(self, range: val::Range<&Self>) -> ValR {
197        match self {
198            Val::Str(b, t @ Tag::Bytes) => Self::range_int(range)
199                .map(|range| skip_take(range, b.len()))
200                .map(|(skip, take)| Val::Str(b.slice(skip..skip + take), t)),
201            Val::Str(s, Tag::Utf8) => Self::range_int(range).map(|range_char| {
202                let byte_index = |num::PosUsize(pos, c)| {
203                    let mut chars = s.char_indices().map(|(start, ..)| start);
204                    if pos {
205                        chars.nth(c).unwrap_or(s.len())
206                    } else {
207                        chars.nth_back(c - 1).unwrap_or(0)
208                    }
209                };
210                let from_byte = range_char.start.map_or(0, byte_index);
211                let upto_byte = range_char.end.map_or(s.len(), byte_index);
212                let slice = &s[from_byte..core::cmp::max(upto_byte, from_byte)];
213                Val::Str(s.slice_ref(slice), Tag::Utf8)
214            }),
215            Val::Arr(a) => Self::range_int(range)
216                .map(|range| skip_take(range, a.len()))
217                .map(|(skip, take)| a.iter().skip(skip).take(take).cloned().collect()),
218            _ => Err(Error::typ(self, Type::Range.as_str())),
219        }
220    }
221
222    fn map_values<I: Iterator<Item = ValX>>(self, opt: path::Opt, f: impl Fn(Self) -> I) -> ValX {
223        match self {
224            Self::Arr(a) => {
225                let iter = rc_unwrap_or_clone(a).into_iter().flat_map(f);
226                Ok(iter.collect::<Result<_, _>>()?)
227            }
228            Self::Obj(o) => {
229                let iter = rc_unwrap_or_clone(o).into_iter();
230                let iter = iter.filter_map(|(k, v)| f(v).next().map(|v| Ok((k, v?))));
231                Ok(Self::obj(iter.collect::<Result<_, Exn<_>>>()?))
232            }
233            v => opt.fail(v, |v| Exn::from(Error::typ(v, Type::Iter.as_str()))),
234        }
235    }
236
237    fn map_index<I: Iterator<Item = ValX>>(
238        mut self,
239        index: &Self,
240        opt: path::Opt,
241        f: impl Fn(Self) -> I,
242    ) -> ValX {
243        match self {
244            Val::Obj(ref mut o) => {
245                use indexmap::map::Entry::{Occupied, Vacant};
246                match Rc::make_mut(o).entry(index.clone()) {
247                    Occupied(mut e) => {
248                        let v = core::mem::take(e.get_mut());
249                        match f(v).next().transpose()? {
250                            Some(y) => e.insert(y),
251                            // this runs in constant time, at the price of
252                            // changing the order of the elements
253                            None => e.swap_remove(),
254                        };
255                    }
256                    Vacant(e) => {
257                        if let Some(y) = f(Val::Null).next().transpose()? {
258                            e.insert(y);
259                        }
260                    }
261                }
262                Ok(self)
263            }
264            Val::Arr(ref mut a) => {
265                let oob = || Error::str(format_args!("index {index} out of bounds"));
266                let abs_or = |i| abs_index(i, a.len()).ok_or_else(oob);
267                let i = match index.as_pos_usize().and_then(abs_or) {
268                    Ok(i) => i,
269                    Err(e) => return opt.fail(self, |_| Exn::from(e)),
270                };
271
272                let a = Rc::make_mut(a);
273                let x = core::mem::take(&mut a[i]);
274                if let Some(y) = f(x).next().transpose()? {
275                    a[i] = y;
276                } else {
277                    a.remove(i);
278                }
279                Ok(self)
280            }
281            _ => opt.fail(self, |v| Exn::from(Error::typ(v, Type::Iter.as_str()))),
282        }
283    }
284
285    fn map_range<I: Iterator<Item = ValX>>(
286        mut self,
287        range: val::Range<&Self>,
288        opt: path::Opt,
289        f: impl Fn(Self) -> I,
290    ) -> ValX {
291        if let Val::Arr(ref mut a) = self {
292            let (skip, take) = match Self::range_int(range) {
293                Ok(range) => skip_take(range, a.len()),
294                Err(e) => return opt.fail(self, |_| Exn::from(e)),
295            };
296            let arr = a.iter().skip(skip).take(take).cloned().collect();
297            let y = f(arr).map(|y| y?.into_arr().map_err(Exn::from)).next();
298            let y = y.transpose()?.unwrap_or_default();
299            Rc::make_mut(a).splice(skip..skip + take, (*y).clone());
300            Ok(self)
301        } else {
302            opt.fail(self, |v| Exn::from(Error::typ(v, Type::Arr.as_str())))
303        }
304    }
305
306    /// True if the value is neither null nor false.
307    fn as_bool(&self) -> bool {
308        !matches!(self, Self::Null | Self::Bool(false))
309    }
310
311    fn into_string(self) -> Self {
312        if let Self::Str(b, _tag) = self {
313            Self::utf8_str(b)
314        } else {
315            Self::utf8_str(self.to_json())
316        }
317    }
318}
319
320impl jaq_std::ValT for Val {
321    fn into_seq<S: FromIterator<Self>>(self) -> Result<S, Self> {
322        match self {
323            Self::Arr(a) => match Rc::try_unwrap(a) {
324                Ok(a) => Ok(a.into_iter().collect()),
325                Err(a) => Ok(a.iter().cloned().collect()),
326            },
327            _ => Err(self),
328        }
329    }
330
331    fn is_int(&self) -> bool {
332        self.as_num().is_some_and(Num::is_int)
333    }
334
335    fn as_isize(&self) -> Option<isize> {
336        self.as_num().and_then(Num::as_isize)
337    }
338
339    fn as_f64(&self) -> Option<f64> {
340        self.as_num().map(Num::as_f64)
341    }
342
343    fn is_utf8_str(&self) -> bool {
344        matches!(self, Self::Str(_, Tag::Utf8))
345    }
346
347    fn as_bytes(&self) -> Option<&[u8]> {
348        if let Self::Str(b, _) = self {
349            Some(b)
350        } else {
351            None
352        }
353    }
354
355    fn as_sub_str(&self, sub: &[u8]) -> Self {
356        match self {
357            Self::Str(b, tag) => Self::Str(b.slice_ref(sub), *tag),
358            _ => panic!(),
359        }
360    }
361
362    fn from_utf8_bytes(b: impl AsRef<[u8]> + Send + 'static) -> Self {
363        Self::Str(Bytes::from_owner(b), Tag::Utf8)
364    }
365}
366
367/// Definitions of the standard library.
368pub fn defs() -> impl Iterator<Item = load::parse::Def<&'static str>> {
369    load::parse(include_str!("defs.jq"), |p| p.defs())
370        .unwrap()
371        .into_iter()
372}
373
374fn skip_take(range: val::Range<num::PosUsize>, len: usize) -> (usize, usize) {
375    let from = abs_bound(range.start, len, 0);
376    let upto = abs_bound(range.end, len, len);
377    (from, upto.saturating_sub(from))
378}
379
380/// If a range bound is given, absolutise and clip it between 0 and `len`,
381/// else return `default`.
382fn abs_bound(i: Option<num::PosUsize>, len: usize, default: usize) -> usize {
383    i.map_or(default, |i| core::cmp::min(i.wrap(len).unwrap_or(0), len))
384}
385
386/// Absolutise an index and return result if it is inside [0, len).
387fn abs_index(i: num::PosUsize, len: usize) -> Option<usize> {
388    i.wrap(len).filter(|i| *i < len)
389}
390
391impl Val {
392    /// Construct an object value.
393    pub fn obj(m: Map) -> Self {
394        Self::Obj(m.into())
395    }
396
397    /// Construct a string that is interpreted as UTF-8.
398    pub fn utf8_str(s: impl Into<Bytes>) -> Self {
399        Self::Str(s.into(), Tag::Utf8)
400    }
401
402    /// Construct a string that is interpreted as bytes.
403    pub fn byte_str(s: impl Into<Bytes>) -> Self {
404        Self::Str(s.into(), Tag::Bytes)
405    }
406
407    fn as_num(&self) -> Option<&Num> {
408        match self {
409            Self::Num(n) => Some(n),
410            _ => None,
411        }
412    }
413
414    /// If the value is an integer in [-usize::MAX, +usize::MAX], return it, else fail.
415    fn as_pos_usize(&self) -> Result<num::PosUsize, Error> {
416        let fail = || Error::typ(self.clone(), Type::Int.as_str());
417        self.as_num().and_then(Num::as_pos_usize).ok_or_else(fail)
418    }
419
420    /// If the value is an array, return it, else fail.
421    fn into_arr(self) -> Result<Rc<Vec<Self>>, Error> {
422        match self {
423            Self::Arr(a) => Ok(a),
424            _ => Err(Error::typ(self, Type::Arr.as_str())),
425        }
426    }
427
428    fn as_arr(&self) -> Result<&Rc<Vec<Self>>, Error> {
429        match self {
430            Self::Arr(a) => Ok(a),
431            _ => Err(Error::typ(self.clone(), Type::Arr.as_str())),
432        }
433    }
434
435    fn range_int(range: val::Range<&Self>) -> Result<val::Range<num::PosUsize>, Error> {
436        let (from, upto) = (range.start, range.end);
437        let from = from.as_ref().map(|i| i.as_pos_usize()).transpose();
438        let upto = upto.as_ref().map(|i| i.as_pos_usize()).transpose();
439        Ok(from?..upto?)
440    }
441
442    fn to_json(&self) -> Vec<u8> {
443        let mut buf = Vec::new();
444        write::write(&mut buf, self).unwrap();
445        buf
446    }
447}
448
449impl From<bool> for Val {
450    fn from(b: bool) -> Self {
451        Self::Bool(b)
452    }
453}
454
455impl From<isize> for Val {
456    fn from(i: isize) -> Self {
457        Self::Num(Num::Int(i))
458    }
459}
460
461impl From<usize> for Val {
462    fn from(i: usize) -> Self {
463        Self::Num(Num::from_integral(i))
464    }
465}
466
467impl From<f64> for Val {
468    fn from(f: f64) -> Self {
469        Self::Num(Num::Float(f))
470    }
471}
472
473impl From<String> for Val {
474    fn from(s: String) -> Self {
475        Self::Str(Bytes::from_owner(s), Tag::Utf8)
476    }
477}
478
479impl From<val::Range<Val>> for Val {
480    fn from(r: val::Range<Val>) -> Self {
481        let kv = |(k, v): (&str, Option<_>)| v.map(|v| (k.to_owned().into(), v));
482        let kvs = [("start", r.start), ("end", r.end)];
483        Val::obj(kvs.into_iter().flat_map(kv).collect())
484    }
485}
486
487impl FromIterator<Self> for Val {
488    fn from_iter<T: IntoIterator<Item = Self>>(iter: T) -> Self {
489        Self::Arr(Rc::new(iter.into_iter().collect()))
490    }
491}
492
493fn bigint_to_int_saturated(i: &BigInt) -> isize {
494    let (min, max) = (isize::MIN, isize::MAX);
495    i.to_isize()
496        .unwrap_or_else(|| if i.is_negative() { min } else { max })
497}
498
499impl core::ops::Add for Val {
500    type Output = ValR;
501    fn add(self, rhs: Self) -> Self::Output {
502        use Val::*;
503        match (self, rhs) {
504            // `null` is a neutral element for addition
505            (Null, x) | (x, Null) => Ok(x),
506            (Num(x), Num(y)) => Ok(Num(x + y)),
507            (Str(l, tag), Str(r, tag_)) if tag == tag_ => {
508                let mut buf = BytesMut::from(l);
509                buf.put(r);
510                Ok(Str(buf.into(), tag))
511            }
512            (Arr(mut l), Arr(r)) => {
513                //std::dbg!(Rc::strong_count(&l));
514                Rc::make_mut(&mut l).extend(r.iter().cloned());
515                Ok(Arr(l))
516            }
517            (Obj(mut l), Obj(r)) => {
518                Rc::make_mut(&mut l).extend(r.iter().map(|(k, v)| (k.clone(), v.clone())));
519                Ok(Obj(l))
520            }
521            (l, r) => Err(Error::math(l, ops::Math::Add, r)),
522        }
523    }
524}
525
526impl core::ops::Sub for Val {
527    type Output = ValR;
528    fn sub(self, rhs: Self) -> Self::Output {
529        match (self, rhs) {
530            (Self::Num(x), Self::Num(y)) => Ok(Self::Num(x - y)),
531            (Self::Arr(mut l), Self::Arr(r)) => {
532                let r = r.iter().collect::<alloc::collections::BTreeSet<_>>();
533                Rc::make_mut(&mut l).retain(|x| !r.contains(x));
534                Ok(Self::Arr(l))
535            }
536            (l, r) => Err(Error::math(l, ops::Math::Sub, r)),
537        }
538    }
539}
540
541fn obj_merge(l: &mut Rc<Map>, r: Rc<Map>) {
542    let l = Rc::make_mut(l);
543    let r = rc_unwrap_or_clone(r).into_iter();
544    r.for_each(|(k, v)| match (l.get_mut(&k), v) {
545        (Some(Val::Obj(l)), Val::Obj(r)) => obj_merge(l, r),
546        (Some(l), r) => *l = r,
547        (None, r) => {
548            l.insert(k, r);
549        }
550    });
551}
552
553impl core::ops::Mul for Val {
554    type Output = ValR;
555    fn mul(self, rhs: Self) -> Self::Output {
556        use crate::Num::{BigInt, Int};
557        use Val::*;
558        match (self, rhs) {
559            (Num(x), Num(y)) => Ok(Num(x * y)),
560            (s @ Str(..), Num(BigInt(i))) | (Num(BigInt(i)), s @ Str(..)) => {
561                s * Num(Int(bigint_to_int_saturated(&i)))
562            }
563            (Str(s, tag), Num(Int(i))) | (Num(Int(i)), Str(s, tag)) if i > 0 => {
564                Ok(Self::Str(s.repeat(i as usize).into(), tag))
565            }
566            // string multiplication with negatives or 0 results in null
567            // <https://jqlang.github.io/jq/manual/#Builtinoperatorsandfunctions>
568            (Str(..), Num(Int(_))) | (Num(Int(_)), Str(..)) => Ok(Null),
569            (Obj(mut l), Obj(r)) => {
570                obj_merge(&mut l, r);
571                Ok(Obj(l))
572            }
573            (l, r) => Err(Error::math(l, ops::Math::Mul, r)),
574        }
575    }
576}
577
578/// Split a string by a given separator string.
579fn split<'a>(s: &'a [u8], sep: &'a [u8]) -> Box<dyn Iterator<Item = &'a [u8]> + 'a> {
580    if s.is_empty() {
581        Box::new(core::iter::empty())
582    } else if sep.is_empty() {
583        // Rust's `split` function with an empty separator ("")
584        // yields an empty string as first and last result
585        // to prevent this, we are using `chars` instead
586        Box::new(s.char_indices().map(|(start, end, _)| &s[start..end]))
587    } else {
588        Box::new(s.split_str(sep))
589    }
590}
591
592impl core::ops::Div for Val {
593    type Output = ValR;
594    fn div(self, rhs: Self) -> Self::Output {
595        match (self, rhs) {
596            (Self::Num(x), Self::Num(y)) => Ok(Self::Num(x / y)),
597            (Self::Str(x, tag), Self::Str(y, tag_)) if tag == tag_ => Ok(split(&x, &y)
598                .map(|s| Val::Str(x.slice_ref(s), tag))
599                .collect()),
600            (l, r) => Err(Error::math(l, ops::Math::Div, r)),
601        }
602    }
603}
604
605impl core::ops::Rem for Val {
606    type Output = ValR;
607    fn rem(self, rhs: Self) -> Self::Output {
608        match (self, rhs) {
609            (Self::Num(x), Self::Num(y)) if !(x.is_int() && y.is_int() && y == Num::Int(0)) => {
610                Ok(Self::Num(x % y))
611            }
612            (l, r) => Err(Error::math(l, ops::Math::Rem, r)),
613        }
614    }
615}
616
617impl core::ops::Neg for Val {
618    type Output = ValR;
619    fn neg(self) -> Self::Output {
620        match self {
621            Self::Num(n) => Ok(Self::Num(-n)),
622            x => Err(Error::typ(x, Type::Num.as_str())),
623        }
624    }
625}
626
627impl PartialOrd for Val {
628    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
629        Some(self.cmp(other))
630    }
631}
632
633impl Ord for Val {
634    fn cmp(&self, other: &Self) -> Ordering {
635        use Ordering::{Equal, Greater, Less};
636        match (self, other) {
637            (Self::Null, Self::Null) => Equal,
638            (Self::Bool(x), Self::Bool(y)) => x.cmp(y),
639            (Self::Num(x), Self::Num(y)) => x.cmp(y),
640            (Self::Str(x, _), Self::Str(y, _)) => x.cmp(y),
641            (Self::Arr(x), Self::Arr(y)) => x.cmp(y),
642            (Self::Obj(x), Self::Obj(y)) => match (x.len(), y.len()) {
643                (0, 0) => Equal,
644                (0, _) => Less,
645                (_, 0) => Greater,
646                _ => {
647                    let mut l: Vec<_> = x.iter().collect();
648                    let mut r: Vec<_> = y.iter().collect();
649                    l.sort_by_key(|(k, _v)| *k);
650                    r.sort_by_key(|(k, _v)| *k);
651                    // TODO: make this nicer
652                    let kl = l.iter().map(|(k, _v)| k);
653                    let kr = r.iter().map(|(k, _v)| k);
654                    let vl = l.iter().map(|(_k, v)| v);
655                    let vr = r.iter().map(|(_k, v)| v);
656                    kl.cmp(kr).then_with(|| vl.cmp(vr))
657                }
658            },
659
660            // nulls are smaller than anything else
661            (Self::Null, _) => Less,
662            (_, Self::Null) => Greater,
663            // bools are smaller than anything else, except for nulls
664            (Self::Bool(_), _) => Less,
665            (_, Self::Bool(_)) => Greater,
666            // numbers are smaller than anything else, except for nulls and bools
667            (Self::Num(_), _) => Less,
668            (_, Self::Num(_)) => Greater,
669            // etc.
670            (Self::Str(..), _) => Less,
671            (_, Self::Str(..)) => Greater,
672            (Self::Arr(_), _) => Less,
673            (_, Self::Arr(_)) => Greater,
674        }
675    }
676}
677
678impl PartialEq for Val {
679    fn eq(&self, other: &Self) -> bool {
680        match (self, other) {
681            (Self::Null, Self::Null) => true,
682            (Self::Bool(x), Self::Bool(y)) => x == y,
683            (Self::Num(x), Self::Num(y)) => x == y,
684            (Self::Str(x, _tag), Self::Str(y, _)) => x == y,
685            (Self::Arr(x), Self::Arr(y)) => x == y,
686            (Self::Obj(x), Self::Obj(y)) => x == y,
687            _ => false,
688        }
689    }
690}
691
692impl Eq for Val {}
693
694impl Hash for Val {
695    fn hash<H: Hasher>(&self, state: &mut H) {
696        fn hash_with(u: u8, x: impl Hash, state: &mut impl Hasher) {
697            state.write_u8(u);
698            x.hash(state)
699        }
700        match self {
701            Self::Num(n) => n.hash(state),
702            // Num::hash() starts its hash with a 0 or 1, so we start with 2 here
703            Self::Null => state.write_u8(2),
704            Self::Bool(b) => state.write_u8(if *b { 3 } else { 4 }),
705            Self::Str(b, _) => hash_with(5, b, state),
706            Self::Arr(a) => hash_with(6, a, state),
707            Self::Obj(o) => {
708                state.write_u8(7);
709                // this is similar to what happens in `Val::cmp`
710                let mut kvs: Vec<_> = o.iter().collect();
711                kvs.sort_by_key(|(k, _v)| *k);
712                kvs.iter().for_each(|(k, v)| (k, v).hash(state));
713            }
714        }
715    }
716}
717
718/// Display bytes as valid UTF-8 string.
719///
720/// This maps invalid UTF-8 to the Unicode replacement character.
721pub fn bstr(s: &(impl core::convert::AsRef<[u8]> + ?Sized)) -> impl fmt::Display + '_ {
722    BStr::new(s)
723}
724
725impl fmt::Display for Val {
726    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
727        write_val!(f, self, |v: &Val| v.fmt(f))
728    }
729}
730
731/// Dynamic & thread-safe [`std::error::Error`].
732pub type BoxError = Box<dyn std::error::Error + Send + Sync>;
733
734/// Create an invalid data I/O error.
735pub fn invalid_data(e: impl Into<BoxError>) -> std::io::Error {
736    std::io::Error::new(std::io::ErrorKind::InvalidData, e)
737}