1#![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#[derive(Clone, Debug, Default)]
59pub enum Val {
60 #[default]
61 Null,
63 Bool(bool),
65 Num(Num),
67 Str(Bytes, Tag),
69 Arr(Rc<Vec<Val>>),
71 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#[derive(Copy, Clone, Debug, PartialEq, Eq)]
87pub enum Tag {
88 Bytes,
90 Utf8,
97}
98
99#[derive(Clone, Debug, PartialEq, Eq)]
101enum Type {
102 Int,
104 Num,
110 Arr,
116 Iter,
118 Range,
120}
121
122impl Type {
123 fn as_str(&self) -> &'static str {
124 match self {
125 Self::Int => "integer",
126 Self::Num => "number",
128 Self::Arr => "array",
130 Self::Iter => "iterable (array or object)",
131 Self::Range => "rangeable (array or string)",
132 }
133 }
134}
135
136pub type Map<K = Val, V = K> = indexmap::IndexMap<K, V, foldhash::fast::RandomState>;
138
139pub type Error = jaq_core::Error<Val>;
141pub type ValR = jaq_core::ValR<Val>;
143pub type ValX = jaq_core::ValX<Val>;
145
146fn 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 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 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
367pub 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
380fn 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
386fn abs_index(i: num::PosUsize, len: usize) -> Option<usize> {
388 i.wrap(len).filter(|i| *i < len)
389}
390
391impl Val {
392 pub fn obj(m: Map) -> Self {
394 Self::Obj(m.into())
395 }
396
397 pub fn utf8_str(s: impl Into<Bytes>) -> Self {
399 Self::Str(s.into(), Tag::Utf8)
400 }
401
402 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 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 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, 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 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 (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
578fn 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 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 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 (Self::Null, _) => Less,
662 (_, Self::Null) => Greater,
663 (Self::Bool(_), _) => Less,
665 (_, Self::Bool(_)) => Greater,
666 (Self::Num(_), _) => Less,
668 (_, Self::Num(_)) => Greater,
669 (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 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 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
718pub 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
731pub type BoxError = Box<dyn std::error::Error + Send + Sync>;
733
734pub fn invalid_data(e: impl Into<BoxError>) -> std::io::Error {
736 std::io::Error::new(std::io::ErrorKind::InvalidData, e)
737}