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