1#![no_std]
7#![forbid(unsafe_code)]
8#![warn(missing_docs)]
9
10extern crate alloc;
11#[cfg(feature = "std")]
12extern crate std;
13
14mod funs;
15mod num;
16#[macro_use]
17pub mod write;
18pub mod read;
19
20use alloc::{borrow::ToOwned, boxed::Box, string::String, vec::Vec};
21use bstr::{BStr, ByteSlice};
22use bytes::{BufMut, Bytes, BytesMut};
23use core::cmp::Ordering;
24use core::fmt;
25use core::hash::{Hash, Hasher};
26use jaq_core::box_iter::box_once;
27use jaq_core::{load, ops, path, val, Exn};
28use num_bigint::BigInt;
29use num_traits::{cast::ToPrimitive, Signed};
30
31pub use funs::{bytes_valrs, funs};
32pub use num::Num;
33
34#[cfg(not(feature = "sync"))]
35pub use alloc::rc::Rc;
36#[cfg(feature = "sync")]
37pub use alloc::sync::Arc as Rc;
38
39#[cfg(feature = "serde")]
40mod serde;
41
42#[derive(Clone, Debug, Default)]
46pub enum Val {
47 #[default]
48 Null,
50 Bool(bool),
52 Num(Num),
54 BStr(Box<Bytes>),
56 TStr(Box<Bytes>),
63 Arr(Rc<Vec<Val>>),
65 Obj(Rc<Map<Val, Val>>),
67}
68
69#[cfg(feature = "sync")]
70#[test]
71fn val_send_sync() {
72 fn send_sync<T: Send + Sync>(_: T) {}
73 send_sync(Val::default())
74}
75
76#[cfg(target_arch = "x86_64")]
77const _: () = {
78 assert!(core::mem::size_of::<Val>() == 16);
79};
80
81#[derive(Clone, Debug, PartialEq, Eq)]
83enum Type {
84 Int,
86 Num,
92 Str,
94 Arr,
96 Iter,
98 Range,
100}
101
102impl Type {
103 fn as_str(&self) -> &'static str {
104 match self {
105 Self::Int => "integer",
106 Self::Num => "number",
108 Self::Str => "string",
109 Self::Arr => "array",
110 Self::Iter => "iterable (array or object)",
111 Self::Range => "rangeable (array or string)",
112 }
113 }
114}
115
116pub type Map<K = Val, V = K> = indexmap::IndexMap<K, V, foldhash::fast::RandomState>;
118
119pub type Error = jaq_core::Error<Val>;
121pub type ValR = jaq_core::ValR<Val>;
123pub type ValX<'a> = jaq_core::ValX<'a, Val>;
125
126fn rc_unwrap_or_clone<T: Clone>(a: Rc<T>) -> T {
130 Rc::try_unwrap(a).unwrap_or_else(|a| (*a).clone())
131}
132
133impl jaq_core::ValT for Val {
134 fn from_num(n: &str) -> ValR {
135 Ok(Self::Num(Num::from_str(n)))
136 }
137
138 fn from_map<I: IntoIterator<Item = (Self, Self)>>(iter: I) -> ValR {
139 Ok(Self::obj(iter.into_iter().collect()))
140 }
141
142 fn key_values(self) -> Box<dyn Iterator<Item = Result<(Val, Val), Error>>> {
143 let arr_idx = |(i, x)| Ok((Self::from(i as isize), x));
144 match self {
145 Self::Arr(a) => Box::new(rc_unwrap_or_clone(a).into_iter().enumerate().map(arr_idx)),
146 Self::Obj(o) => Box::new(rc_unwrap_or_clone(o).into_iter().map(Ok)),
147 _ => box_once(Err(Error::typ(self, Type::Iter.as_str()))),
148 }
149 }
150
151 fn values(self) -> Box<dyn Iterator<Item = ValR>> {
152 match self {
153 Self::Arr(a) => Box::new(rc_unwrap_or_clone(a).into_iter().map(Ok)),
154 Self::Obj(o) => Box::new(rc_unwrap_or_clone(o).into_iter().map(|(_k, v)| Ok(v))),
155 _ => box_once(Err(Error::typ(self, Type::Iter.as_str()))),
156 }
157 }
158
159 fn index(self, index: &Self) -> ValR {
160 self.index_opt(index).map(|o| o.unwrap_or(Val::Null))
161 }
162
163 fn range(self, range: val::Range<&Self>) -> ValR {
164 let fs = |b: Bytes, range, skip_take: SkipTakeFn| {
165 Self::range_int(range)
166 .map(|range_char| skip_take(range_char, &b))
167 .map(|(skip, take)| b.slice(skip..skip + take))
168 };
169 match self {
170 Val::BStr(b) => fs(*b, range, skip_take_bytes).map(Val::byte_str),
171 Val::TStr(b) => fs(*b, range, skip_take_chars).map(Val::utf8_str),
172 Val::Arr(a) => Self::range_int(range)
173 .map(|range| skip_take(range, a.len()))
174 .map(|(skip, take)| a.iter().skip(skip).take(take).cloned().collect()),
175 _ => Err(Error::typ(self, Type::Range.as_str())),
176 }
177 }
178
179 fn map_values<'a, I: Iterator<Item = ValX<'a>>>(
180 self,
181 opt: path::Opt,
182 f: impl Fn(Self) -> I,
183 ) -> ValX<'a> {
184 match self {
185 Self::Arr(a) => {
186 let iter = rc_unwrap_or_clone(a).into_iter().flat_map(f);
187 Ok(iter.collect::<Result<_, _>>()?)
188 }
189 Self::Obj(o) => {
190 let iter = rc_unwrap_or_clone(o).into_iter();
191 let iter = iter.filter_map(|(k, v)| f(v).next().map(|v| Ok((k, v?))));
192 Ok(Self::obj(iter.collect::<Result<_, Exn<_>>>()?))
193 }
194 v => opt.fail(v, |v| Exn::from(Error::typ(v, Type::Iter.as_str()))),
195 }
196 }
197
198 fn map_index<'a, I: Iterator<Item = ValX<'a>>>(
199 mut self,
200 index: &Self,
201 opt: path::Opt,
202 f: impl Fn(Self) -> I,
203 ) -> ValX<'a> {
204 if let (Val::BStr(_) | Val::TStr(_) | Val::Arr(_), Val::Obj(o)) = (&self, index) {
205 let range = o.get(&Val::utf8_str("start"))..o.get(&Val::utf8_str("end"));
206 return self.map_range(range, opt, f);
207 };
208 match self {
209 Val::Obj(ref mut o) => {
210 use indexmap::map::Entry::{Occupied, Vacant};
211 match Rc::make_mut(o).entry(index.clone()) {
212 Occupied(mut e) => {
213 let v = core::mem::take(e.get_mut());
214 match f(v).next().transpose()? {
215 Some(y) => e.insert(y),
216 None => e.swap_remove(),
219 };
220 }
221 Vacant(e) => {
222 if let Some(y) = f(Val::Null).next().transpose()? {
223 e.insert(y);
224 }
225 }
226 }
227 Ok(self)
228 }
229 Val::Arr(ref mut a) => {
230 let oob = || Error::str(format_args!("index {index} out of bounds"));
231 let abs_or = |i| abs_index(i, a.len()).ok_or_else(oob);
232 let i = match index.as_pos_usize().and_then(abs_or) {
233 Ok(i) => i,
234 Err(e) => return opt.fail(self, |_| Exn::from(e)),
235 };
236
237 let a = Rc::make_mut(a);
238 let x = core::mem::take(&mut a[i]);
239 if let Some(y) = f(x).next().transpose()? {
240 a[i] = y;
241 } else {
242 a.remove(i);
243 }
244 Ok(self)
245 }
246 _ => opt.fail(self, |v| Exn::from(Error::typ(v, Type::Iter.as_str()))),
247 }
248 }
249
250 fn map_range<'a, I: Iterator<Item = ValX<'a>>>(
251 mut self,
252 range: val::Range<&Self>,
253 opt: path::Opt,
254 f: impl Fn(Self) -> I,
255 ) -> ValX<'a> {
256 let fs = |b: Bytes, range, skip_take: SkipTakeFn, from: ValBytesFn, into: BytesValFn| {
257 let (skip, take) = match Self::range_int(range) {
258 Ok(range) => skip_take(range, &b),
259 Err(e) => return opt.fail(into(b), |_| Exn::from(e)),
260 };
261 let str = into(b.slice(skip..skip + take));
262 let y = f(str).map(|y| from(y?).map_err(Exn::from)).next();
263 let y = y.transpose()?.unwrap_or_default();
264 let mut b = BytesMut::from(b);
265 bytes_splice(&mut b, skip, take, &y);
266 Ok(into(b.freeze()))
267 };
268 let stb = skip_take_bytes;
269 let stc = skip_take_chars;
270 match self {
271 Val::Arr(ref mut a) => {
272 let (skip, take) = match Self::range_int(range) {
273 Ok(range) => skip_take(range, a.len()),
274 Err(e) => return opt.fail(self, |_| Exn::from(e)),
275 };
276 let arr = a.iter().skip(skip).take(take).cloned().collect();
277 let y = f(arr).map(|y| y?.into_arr().map_err(Exn::from)).next();
278 let y = y.transpose()?.unwrap_or_default();
279 Rc::make_mut(a).splice(skip..skip + take, (*y).clone());
280 Ok(self)
281 }
282 Val::BStr(b) => fs(*b, range, stb, Val::into_byte_str, Val::byte_str),
283 Val::TStr(b) => fs(*b, range, stc, Val::into_utf8_str, Val::utf8_str),
284 _ => opt.fail(self, |v| Exn::from(Error::typ(v, Type::Arr.as_str()))),
285 }
286 }
287
288 fn as_bool(&self) -> bool {
290 !matches!(self, Self::Null | Self::Bool(false))
291 }
292
293 fn into_string(self) -> Self {
294 match self {
295 Self::BStr(b) | Self::TStr(b) => Self::TStr(b),
296 _ => Self::utf8_str(self.to_json()),
297 }
298 }
299}
300
301impl jaq_std::ValT for Val {
302 fn into_seq<S: FromIterator<Self>>(self) -> Result<S, Self> {
303 match self {
304 Self::Arr(a) => match Rc::try_unwrap(a) {
305 Ok(a) => Ok(a.into_iter().collect()),
306 Err(a) => Ok(a.iter().cloned().collect()),
307 },
308 _ => Err(self),
309 }
310 }
311
312 fn is_int(&self) -> bool {
313 self.as_num().is_some_and(Num::is_int)
314 }
315
316 fn as_isize(&self) -> Option<isize> {
317 self.as_num().and_then(Num::as_isize)
318 }
319
320 fn as_f64(&self) -> Option<f64> {
321 self.as_num().map(Num::as_f64)
322 }
323
324 fn is_utf8_str(&self) -> bool {
325 matches!(self, Self::TStr(_))
326 }
327
328 fn as_bytes(&self) -> Option<&[u8]> {
329 match self {
330 Self::BStr(b) | Self::TStr(b) => Some(b),
331 _ => None,
332 }
333 }
334
335 fn as_sub_str(&self, sub: &[u8]) -> Self {
336 match self {
337 Self::BStr(b) => Self::byte_str(b.slice_ref(sub)),
338 Self::TStr(b) => Self::utf8_str(b.slice_ref(sub)),
339 _ => panic!(),
340 }
341 }
342
343 fn from_utf8_bytes(b: impl AsRef<[u8]> + Send + 'static) -> Self {
344 Self::utf8_str(Bytes::from_owner(b))
345 }
346}
347
348pub fn defs() -> impl Iterator<Item = load::parse::Def<&'static str>> {
350 load::parse(include_str!("defs.jq"), |p| p.defs())
351 .unwrap()
352 .into_iter()
353}
354
355type ValBytesFn = fn(Val) -> Result<Bytes, Error>;
356type BytesValFn = fn(Bytes) -> Val;
357type SkipTakeFn = fn(val::Range<num::PosUsize>, &[u8]) -> (usize, usize);
358
359fn skip_take(range: val::Range<num::PosUsize>, len: usize) -> (usize, usize) {
360 let from = abs_bound(range.start, len, 0);
361 let upto = abs_bound(range.end, len, len);
362 (from, upto.saturating_sub(from))
363}
364
365fn skip_take_bytes(range: val::Range<num::PosUsize>, b: &[u8]) -> (usize, usize) {
366 skip_take(range, b.len())
367}
368
369fn skip_take_chars(range: val::Range<num::PosUsize>, b: &[u8]) -> (usize, usize) {
370 let byte_index = |num::PosUsize(pos, c)| {
371 let mut chars = b.char_indices().map(|(start, ..)| start);
372 if pos {
373 chars.nth(c).unwrap_or(b.len())
374 } else {
375 chars.nth_back(c - 1).unwrap_or(0)
376 }
377 };
378 let from_byte = range.start.map_or(0, byte_index);
379 let upto_byte = range.end.map_or(b.len(), byte_index);
380 (from_byte, upto_byte.saturating_sub(from_byte))
381}
382
383fn bytes_splice(b: &mut BytesMut, skip: usize, take: usize, replace: &[u8]) {
384 let final_len = b.len() - take + replace.len();
385 let post_take = skip + take..b.len();
386
387 if replace.len() > take {
388 b.resize(final_len, 0);
389 }
390 b.copy_within(post_take, skip + replace.len());
391 b[skip..skip + replace.len()].copy_from_slice(replace);
392 if replace.len() < take {
393 b.truncate(final_len);
394 }
395}
396
397fn abs_bound(i: Option<num::PosUsize>, len: usize, default: usize) -> usize {
400 i.map_or(default, |i| core::cmp::min(i.wrap(len).unwrap_or(0), len))
401}
402
403fn abs_index(i: num::PosUsize, len: usize) -> Option<usize> {
405 i.wrap(len).filter(|i| *i < len)
406}
407
408impl Val {
409 pub fn obj(m: Map) -> Self {
411 Self::Obj(m.into())
412 }
413
414 pub fn utf8_str(s: impl Into<Bytes>) -> Self {
416 Self::TStr(s.into().into())
417 }
418
419 pub fn byte_str(s: impl Into<Bytes>) -> Self {
421 Self::BStr(s.into().into())
422 }
423
424 fn as_num(&self) -> Option<&Num> {
425 match self {
426 Self::Num(n) => Some(n),
427 _ => None,
428 }
429 }
430
431 fn as_pos_usize(&self) -> Result<num::PosUsize, Error> {
433 let fail = || Error::typ(self.clone(), Type::Int.as_str());
434 self.as_num().and_then(Num::as_pos_usize).ok_or_else(fail)
435 }
436
437 fn into_byte_str(self) -> Result<Bytes, Error> {
438 match self {
439 Self::BStr(b) => Ok(*b),
440 _ => Err(Error::typ(self, Type::Str.as_str())),
441 }
442 }
443
444 fn into_utf8_str(self) -> Result<Bytes, Error> {
445 match self {
446 Self::TStr(b) => Ok(*b),
447 _ => Err(Error::typ(self, Type::Str.as_str())),
448 }
449 }
450
451 fn into_arr(self) -> Result<Rc<Vec<Self>>, Error> {
453 match self {
454 Self::Arr(a) => Ok(a),
455 _ => Err(Error::typ(self, Type::Arr.as_str())),
456 }
457 }
458
459 fn as_arr(&self) -> Result<&Rc<Vec<Self>>, Error> {
460 match self {
461 Self::Arr(a) => Ok(a),
462 _ => Err(Error::typ(self.clone(), Type::Arr.as_str())),
463 }
464 }
465
466 fn range_int(range: val::Range<&Self>) -> Result<val::Range<num::PosUsize>, Error> {
467 let f = |i: Option<&Self>| {
468 i.as_ref()
469 .filter(|i| !matches!(i, Val::Null))
470 .map(|i| i.as_pos_usize())
471 .transpose()
472 };
473 Ok(f(range.start)?..f(range.end)?)
474 }
475
476 fn to_json(&self) -> Vec<u8> {
477 let mut buf = write::Buf(Vec::new());
478 write::write_buf(&mut buf, &write::Pp::default(), 0, self).unwrap();
479 buf.0
480 }
481
482 fn index_opt(self, index: &Self) -> Result<Option<Val>, Error> {
483 Ok(match (self, index) {
484 (Val::Null, _) => None,
485 (Val::BStr(a), Val::Num(i @ (Num::Int(_) | Num::BigInt(_)))) => i
486 .as_pos_usize()
487 .and_then(|i| abs_index(i, a.len()))
488 .map(|i| usize::from(a[i]).into()),
489 (Val::Arr(a), Val::Num(i @ (Num::Int(_) | Num::BigInt(_)))) => i
490 .as_pos_usize()
491 .and_then(|i| abs_index(i, a.len()))
492 .map(|i| a[i].clone()),
493 (Val::Arr(_), Val::Arr(y)) if y.is_empty() => Some(Val::Arr(Default::default())),
494 (Val::Arr(x), Val::Arr(y)) => {
495 let iw = x.windows(y.len()).enumerate();
497 let indices = iw.filter_map(|(i, w)| (w == **y).then_some(i));
498 Some(indices.map(Val::from).collect())
499 }
500 (Val::Obj(o), i) => o.get(i).cloned(),
501 (v @ (Val::BStr(_) | Val::TStr(_) | Val::Arr(_)), Val::Obj(o)) => {
502 use jaq_core::ValT;
503 let start = o.get(&Val::utf8_str("start"));
504 let end = o.get(&Val::utf8_str("end"));
505 return v.range(start..end).map(Some);
506 }
507 (s, _) => return Err(Error::index(s, index.clone())),
508 })
509 }
510}
511
512impl From<bool> for Val {
513 fn from(b: bool) -> Self {
514 Self::Bool(b)
515 }
516}
517
518impl From<isize> for Val {
519 fn from(i: isize) -> Self {
520 Self::Num(Num::Int(i))
521 }
522}
523
524impl From<usize> for Val {
525 fn from(i: usize) -> Self {
526 Self::Num(Num::from_integral(i))
527 }
528}
529
530impl From<f64> for Val {
531 fn from(f: f64) -> Self {
532 Self::Num(Num::Float(f))
533 }
534}
535
536impl From<String> for Val {
537 fn from(s: String) -> Self {
538 Self::utf8_str(Bytes::from_owner(s))
539 }
540}
541
542impl From<val::Range<Val>> for Val {
543 fn from(r: val::Range<Val>) -> Self {
544 let kv = |(k, v): (&str, Option<_>)| v.map(|v| (k.to_owned().into(), v));
545 let kvs = [("start", r.start), ("end", r.end)];
546 Val::obj(kvs.into_iter().flat_map(kv).collect())
547 }
548}
549
550impl FromIterator<Self> for Val {
551 fn from_iter<T: IntoIterator<Item = Self>>(iter: T) -> Self {
552 Self::Arr(Rc::new(iter.into_iter().collect()))
553 }
554}
555
556fn bigint_to_int_saturated(i: &BigInt) -> isize {
557 let (min, max) = (isize::MIN, isize::MAX);
558 i.to_isize()
559 .unwrap_or_else(|| if i.is_negative() { min } else { max })
560}
561
562impl core::ops::Add for Val {
563 type Output = ValR;
564 fn add(self, rhs: Self) -> Self::Output {
565 let concat_bytes = |l, r| {
566 let mut buf = BytesMut::from(l);
567 buf.put(r);
568 buf
569 };
570 use Val::*;
571 match (self, rhs) {
572 (Null, x) | (x, Null) => Ok(x),
574 (Num(x), Num(y)) => Ok(Num(x + y)),
575 (BStr(l), BStr(r)) => Ok(Val::byte_str(concat_bytes(*l, r))),
576 (TStr(l), TStr(r)) => Ok(Val::utf8_str(concat_bytes(*l, r))),
577 (Arr(mut l), Arr(r)) => {
578 Rc::make_mut(&mut l).extend(r.iter().cloned());
580 Ok(Arr(l))
581 }
582 (Obj(mut l), Obj(r)) => {
583 Rc::make_mut(&mut l).extend(r.iter().map(|(k, v)| (k.clone(), v.clone())));
584 Ok(Obj(l))
585 }
586 (l, r) => Err(Error::math(l, ops::Math::Add, r)),
587 }
588 }
589}
590
591impl core::ops::Sub for Val {
592 type Output = ValR;
593 fn sub(self, rhs: Self) -> Self::Output {
594 match (self, rhs) {
595 (Self::Num(x), Self::Num(y)) => Ok(Self::Num(x - y)),
596 (Self::Arr(mut l), Self::Arr(r)) => {
597 let r = r.iter().collect::<alloc::collections::BTreeSet<_>>();
598 Rc::make_mut(&mut l).retain(|x| !r.contains(x));
599 Ok(Self::Arr(l))
600 }
601 (l, r) => Err(Error::math(l, ops::Math::Sub, r)),
602 }
603 }
604}
605
606fn obj_merge(l: &mut Rc<Map>, r: Rc<Map>) {
607 let l = Rc::make_mut(l);
608 let r = rc_unwrap_or_clone(r).into_iter();
609 r.for_each(|(k, v)| match (l.get_mut(&k), v) {
610 (Some(Val::Obj(l)), Val::Obj(r)) => obj_merge(l, r),
611 (Some(l), r) => *l = r,
612 (None, r) => {
613 l.insert(k, r);
614 }
615 });
616}
617
618impl core::ops::Mul for Val {
619 type Output = ValR;
620 fn mul(self, rhs: Self) -> Self::Output {
621 use crate::Num::{BigInt, Int};
622 use Val::*;
623 match (self, rhs) {
624 (Num(x), Num(y)) => Ok(Num(x * y)),
625 (s @ (BStr(_) | TStr(_)), Num(BigInt(i)))
626 | (Num(BigInt(i)), s @ (BStr(_) | TStr(_))) => {
627 s * Num(Int(bigint_to_int_saturated(&i)))
628 }
629 (BStr(s), Num(Int(i))) | (Num(Int(i)), BStr(s)) if i > 0 => {
630 Ok(Self::byte_str(s.repeat(i as usize)))
631 }
632 (TStr(s), Num(Int(i))) | (Num(Int(i)), TStr(s)) if i > 0 => {
633 Ok(Self::utf8_str(s.repeat(i as usize)))
634 }
635 (BStr(_) | TStr(_), Num(Int(_))) | (Num(Int(_)), BStr(_) | TStr(_)) => Ok(Null),
638 (Obj(mut l), Obj(r)) => {
639 obj_merge(&mut l, r);
640 Ok(Obj(l))
641 }
642 (l, r) => Err(Error::math(l, ops::Math::Mul, r)),
643 }
644 }
645}
646
647fn split<'a>(s: &'a [u8], sep: &'a [u8]) -> Box<dyn Iterator<Item = &'a [u8]> + 'a> {
649 if s.is_empty() {
650 Box::new(core::iter::empty())
651 } else if sep.is_empty() {
652 Box::new(s.char_indices().map(|(start, end, _)| &s[start..end]))
656 } else {
657 Box::new(s.split_str(sep))
658 }
659}
660
661impl core::ops::Div for Val {
662 type Output = ValR;
663 fn div(self, rhs: Self) -> Self::Output {
664 let fs = |x: Bytes, y: Bytes, into: BytesValFn| {
665 split(&x, &y).map(|s| into(x.slice_ref(s))).collect()
666 };
667 match (self, rhs) {
668 (Self::Num(x), Self::Num(y)) => Ok(Self::Num(x / y)),
669 (Self::TStr(x), Self::TStr(y)) => Ok(fs(*x, *y, Val::utf8_str)),
670 (Self::BStr(x), Self::BStr(y)) => Ok(fs(*x, *y, Val::byte_str)),
671 (l, r) => Err(Error::math(l, ops::Math::Div, r)),
672 }
673 }
674}
675
676impl core::ops::Rem for Val {
677 type Output = ValR;
678 fn rem(self, rhs: Self) -> Self::Output {
679 match (self, rhs) {
680 (Self::Num(x), Self::Num(y)) if !(x.is_int() && y.is_int() && y == Num::Int(0)) => {
681 Ok(Self::Num(x % y))
682 }
683 (l, r) => Err(Error::math(l, ops::Math::Rem, r)),
684 }
685 }
686}
687
688impl core::ops::Neg for Val {
689 type Output = ValR;
690 fn neg(self) -> Self::Output {
691 match self {
692 Self::Num(n) => Ok(Self::Num(-n)),
693 x => Err(Error::typ(x, Type::Num.as_str())),
694 }
695 }
696}
697
698impl PartialOrd for Val {
699 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
700 Some(self.cmp(other))
701 }
702}
703
704impl Ord for Val {
705 fn cmp(&self, other: &Self) -> Ordering {
706 use Ordering::{Equal, Greater, Less};
707 match (self, other) {
708 (Self::Null, Self::Null) => Equal,
709 (Self::Bool(x), Self::Bool(y)) => x.cmp(y),
710 (Self::Num(x), Self::Num(y)) => x.cmp(y),
711 (Self::BStr(x) | Self::TStr(x), Self::BStr(y) | Self::TStr(y)) => x.cmp(y),
712 (Self::Arr(x), Self::Arr(y)) => x.cmp(y),
713 (Self::Obj(x), Self::Obj(y)) => match (x.len(), y.len()) {
714 (0, 0) => Equal,
715 (0, _) => Less,
716 (_, 0) => Greater,
717 _ => {
718 let mut l: Vec<_> = x.iter().collect();
719 let mut r: Vec<_> = y.iter().collect();
720 l.sort_by_key(|(k, _v)| *k);
721 r.sort_by_key(|(k, _v)| *k);
722 let kl = l.iter().map(|(k, _v)| k);
724 let kr = r.iter().map(|(k, _v)| k);
725 let vl = l.iter().map(|(_k, v)| v);
726 let vr = r.iter().map(|(_k, v)| v);
727 kl.cmp(kr).then_with(|| vl.cmp(vr))
728 }
729 },
730
731 (Self::Null, _) => Less,
733 (_, Self::Null) => Greater,
734 (Self::Bool(_), _) => Less,
736 (_, Self::Bool(_)) => Greater,
737 (Self::Num(_), _) => Less,
739 (_, Self::Num(_)) => Greater,
740 (Self::BStr(_) | Self::TStr(_), _) => Less,
742 (_, Self::BStr(_) | Self::TStr(_)) => Greater,
743 (Self::Arr(_), _) => Less,
744 (_, Self::Arr(_)) => Greater,
745 }
746 }
747}
748
749impl PartialEq for Val {
750 fn eq(&self, other: &Self) -> bool {
751 match (self, other) {
752 (Self::Null, Self::Null) => true,
753 (Self::Bool(x), Self::Bool(y)) => x == y,
754 (Self::Num(x), Self::Num(y)) => x == y,
755 (Self::BStr(x) | Self::TStr(x), Self::BStr(y) | Self::TStr(y)) => x == y,
756 (Self::Arr(x), Self::Arr(y)) => x == y,
757 (Self::Obj(x), Self::Obj(y)) => x == y,
758 _ => false,
759 }
760 }
761}
762
763impl Eq for Val {}
764
765impl Hash for Val {
766 fn hash<H: Hasher>(&self, state: &mut H) {
767 fn hash_with(u: u8, x: impl Hash, state: &mut impl Hasher) {
768 state.write_u8(u);
769 x.hash(state)
770 }
771 match self {
772 Self::Num(n) => n.hash(state),
773 Self::Null => state.write_u8(2),
775 Self::Bool(b) => state.write_u8(if *b { 3 } else { 4 }),
776 Self::BStr(b) | Self::TStr(b) => hash_with(5, b, state),
777 Self::Arr(a) => hash_with(6, a, state),
778 Self::Obj(o) => {
779 state.write_u8(7);
780 let mut kvs: Vec<_> = o.iter().collect();
782 kvs.sort_by_key(|(k, _v)| *k);
783 kvs.iter().for_each(|(k, v)| (k, v).hash(state));
784 }
785 }
786 }
787}
788
789pub fn bstr(s: &(impl core::convert::AsRef<[u8]> + ?Sized)) -> impl fmt::Display + '_ {
793 BStr::new(s)
794}
795
796impl fmt::Display for Val {
797 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
798 write::format(f, &write::Pp::default(), 0, self)
799 }
800}