1#![no_std]
3#![forbid(unsafe_code)]
4#![warn(missing_docs)]
5
6extern crate alloc;
7
8use alloc::string::{String, ToString};
9use alloc::{boxed::Box, rc::Rc, vec::Vec};
10use core::cmp::Ordering;
11use core::fmt::{self, Debug};
12use jaq_core::box_iter::{box_once, BoxIter};
13use jaq_core::{load, ops, path, Exn, Native, RunPtr};
14use jaq_std::{run, unary, v, Filter};
15
16#[cfg(feature = "hifijson")]
17use hifijson::{LexAlloc, Token};
18
19#[derive(Clone, Debug, Default)]
30pub enum Val {
31 #[default]
32 Null,
34 Bool(bool),
36 Int(isize),
38 Float(f64),
40 Num(Rc<String>),
42 Str(Rc<String>),
44 Arr(Rc<Vec<Val>>),
46 Obj(Rc<Map<Rc<String>, Val>>),
48}
49
50#[derive(Clone, Debug, PartialEq, Eq)]
52enum Type {
53 Int,
55 Float,
57 Num,
59 Str,
61 Arr,
63 Iter,
65 Range,
67}
68
69impl Type {
70 fn as_str(&self) -> &'static str {
71 match self {
72 Self::Int => "integer",
73 Self::Float => "floating-point number",
74 Self::Num => "number",
75 Self::Str => "string",
76 Self::Arr => "array",
77 Self::Iter => "iterable (array or object)",
78 Self::Range => "rangeable (array or string)",
79 }
80 }
81}
82
83type Map<K, V> = indexmap::IndexMap<K, V, foldhash::fast::RandomState>;
85
86pub type Error = jaq_core::Error<Val>;
88pub type ValR = jaq_core::ValR<Val>;
90pub type ValX<'a> = jaq_core::ValX<'a, Val>;
92
93fn rc_unwrap_or_clone<T: Clone>(a: Rc<T>) -> T {
97 Rc::try_unwrap(a).unwrap_or_else(|a| (*a).clone())
98}
99
100impl jaq_core::ValT for Val {
101 fn from_num(n: &str) -> ValR {
102 Ok(Val::Num(Rc::new(n.to_string())))
103 }
104
105 fn from_map<I: IntoIterator<Item = (Self, Self)>>(iter: I) -> ValR {
106 let iter = iter.into_iter().map(|(k, v)| Ok((k.into_str()?, v)));
107 Ok(Self::obj(iter.collect::<Result<_, _>>()?))
108 }
109
110 fn values(self) -> Box<dyn Iterator<Item = ValR>> {
111 match self {
112 Self::Arr(a) => Box::new(rc_unwrap_or_clone(a).into_iter().map(Ok)),
113 Self::Obj(o) => Box::new(rc_unwrap_or_clone(o).into_iter().map(|(_k, v)| Ok(v))),
114 _ => box_once(Err(Error::typ(self, Type::Iter.as_str()))),
115 }
116 }
117
118 fn index(self, index: &Self) -> ValR {
119 match (self, index) {
120 (Val::Arr(a), Val::Int(i)) => {
121 Ok(abs_index(*i, a.len()).map_or(Val::Null, |i| a[i].clone()))
122 }
123 (Val::Obj(o), Val::Str(s)) => Ok(o.get(s).cloned().unwrap_or(Val::Null)),
124 (s @ (Val::Arr(_) | Val::Obj(_)), _) => Err(Error::index(s, index.clone())),
125 (s, _) => Err(Error::typ(s, Type::Iter.as_str())),
126 }
127 }
128
129 fn range(self, range: jaq_core::val::Range<&Self>) -> ValR {
130 let (from, upto) = (range.start, range.end);
131 match self {
132 Val::Arr(a) => {
133 let len = a.len();
134 let from = from.as_ref().map(|i| i.as_int()).transpose();
135 let upto = upto.as_ref().map(|i| i.as_int()).transpose();
136 from.and_then(|from| Ok((from, upto?))).map(|(from, upto)| {
137 let from = abs_bound(from, len, 0);
138 let upto = abs_bound(upto, len, len);
139 let (skip, take) = skip_take(from, upto);
140 a.iter().skip(skip).take(take).cloned().collect()
141 })
142 }
143 Val::Str(s) => {
144 let len = s.chars().count();
145 let from = from.as_ref().map(|i| i.as_int()).transpose();
146 let upto = upto.as_ref().map(|i| i.as_int()).transpose();
147 from.and_then(|from| Ok((from, upto?))).map(|(from, upto)| {
148 let from = abs_bound(from, len, 0);
149 let upto = abs_bound(upto, len, len);
150 let (skip, take) = skip_take(from, upto);
151 Val::from(s.chars().skip(skip).take(take).collect::<String>())
152 })
153 }
154 _ => Err(Error::typ(self, Type::Range.as_str())),
155 }
156 }
157
158 fn map_values<'a, I: Iterator<Item = ValX<'a>>>(
159 self,
160 opt: path::Opt,
161 f: impl Fn(Self) -> I,
162 ) -> ValX<'a> {
163 match self {
164 Self::Arr(a) => {
165 let iter = rc_unwrap_or_clone(a).into_iter().flat_map(f);
166 Ok(iter.collect::<Result<_, _>>()?)
167 }
168 Self::Obj(o) => {
169 let iter = rc_unwrap_or_clone(o).into_iter();
170 let iter = iter.filter_map(|(k, v)| f(v).next().map(|v| Ok((k, v?))));
171 Ok(Self::obj(iter.collect::<Result<_, Exn<_>>>()?))
172 }
173 v => opt.fail(v, |v| Exn::from(Error::typ(v, Type::Iter.as_str()))),
174 }
175 }
176
177 fn map_index<'a, I: Iterator<Item = ValX<'a>>>(
178 mut self,
179 index: &Self,
180 opt: path::Opt,
181 f: impl Fn(Self) -> I,
182 ) -> ValX<'a> {
183 match self {
184 Val::Obj(ref mut o) => {
185 use indexmap::map::Entry::{Occupied, Vacant};
186 let o = Rc::make_mut(o);
187 let i = match index {
188 Val::Str(s) => s,
189 i => return opt.fail(self, |v| Exn::from(Error::index(v, i.clone()))),
190 };
191 match o.entry(Rc::clone(i)) {
192 Occupied(mut e) => {
193 let v = core::mem::take(e.get_mut());
194 match f(v).next().transpose()? {
195 Some(y) => e.insert(y),
196 None => e.swap_remove(),
199 };
200 }
201 Vacant(e) => {
202 if let Some(y) = f(Val::Null).next().transpose()? {
203 e.insert(y);
204 }
205 }
206 }
207 Ok(self)
208 }
209 Val::Arr(ref mut a) => {
210 let a = Rc::make_mut(a);
211 let abs_or = |i| {
212 abs_index(i, a.len()).ok_or(Error::str(format_args!("index {i} out of bounds")))
213 };
214 let i = match index.as_int().and_then(abs_or) {
215 Ok(i) => i,
216 Err(e) => return opt.fail(self, |_| Exn::from(e)),
217 };
218
219 let x = core::mem::take(&mut a[i]);
220 if let Some(y) = f(x).next().transpose()? {
221 a[i] = y;
222 } else {
223 a.remove(i);
224 }
225 Ok(self)
226 }
227 _ => opt.fail(self, |v| Exn::from(Error::typ(v, Type::Iter.as_str()))),
228 }
229 }
230
231 fn map_range<'a, I: Iterator<Item = ValX<'a>>>(
232 mut self,
233 range: jaq_core::val::Range<&Self>,
234 opt: path::Opt,
235 f: impl Fn(Self) -> I,
236 ) -> ValX<'a> {
237 if let Val::Arr(ref mut a) = self {
238 let a = Rc::make_mut(a);
239 let from = range.start.as_ref().map(|i| i.as_int()).transpose();
240 let upto = range.end.as_ref().map(|i| i.as_int()).transpose();
241 let (from, upto) = match from.and_then(|from| Ok((from, upto?))) {
242 Ok(from_upto) => from_upto,
243 Err(e) => return opt.fail(self, |_| Exn::from(e)),
244 };
245 let len = a.len();
246 let from = abs_bound(from, len, 0);
247 let upto = abs_bound(upto, len, len);
248 let (skip, take) = skip_take(from, upto);
249 let arr = a.iter().skip(skip).take(take).cloned().collect();
250 let y = f(arr).map(|y| y?.into_arr().map_err(Exn::from)).next();
251 let y = y.transpose()?.unwrap_or_default();
252 a.splice(skip..skip + take, (*y).clone());
253 Ok(self)
254 } else {
255 opt.fail(self, |v| Exn::from(Error::typ(v, Type::Arr.as_str())))
256 }
257 }
258
259 fn as_bool(&self) -> bool {
261 !matches!(self, Self::Null | Self::Bool(false))
262 }
263
264 fn as_str(&self) -> Option<&str> {
266 if let Self::Str(s) = self {
267 Some(s)
268 } else {
269 None
270 }
271 }
272}
273
274impl jaq_std::ValT for Val {
275 fn into_seq<S: FromIterator<Self>>(self) -> Result<S, Self> {
276 match self {
277 Self::Arr(a) => match Rc::try_unwrap(a) {
278 Ok(a) => Ok(a.into_iter().collect()),
279 Err(a) => Ok(a.iter().cloned().collect()),
280 },
281 _ => Err(self),
282 }
283 }
284
285 fn as_isize(&self) -> Option<isize> {
286 match self {
287 Self::Int(i) => Some(*i),
288 _ => None,
289 }
290 }
291
292 fn as_f64(&self) -> Result<f64, Error> {
293 Self::as_float(self)
294 }
295}
296
297pub fn defs() -> impl Iterator<Item = load::parse::Def<&'static str>> {
299 load::parse(include_str!("defs.jq"), |p| p.defs())
300 .unwrap()
301 .into_iter()
302}
303
304impl Val {
305 fn length(&self) -> ValR {
310 match self {
311 Val::Null => Ok(Val::Int(0)),
312 Val::Bool(_) => Err(Error::str(format_args!("{self} has no length"))),
313 Val::Int(i) => Ok(Val::Int(i.abs())),
314 Val::Num(n) => Val::from_dec_str(n).length(),
315 Val::Float(f) => Ok(Val::Float(f.abs())),
316 Val::Str(s) => Ok(Val::Int(s.chars().count() as isize)),
317 Val::Arr(a) => Ok(Val::Int(a.len() as isize)),
318 Val::Obj(o) => Ok(Val::Int(o.len() as isize)),
319 }
320 }
321
322 fn indices<'a>(&'a self, y: &'a Val) -> Result<Box<dyn Iterator<Item = usize> + 'a>, Error> {
324 match (self, y) {
325 (Val::Str(_), Val::Str(y)) if y.is_empty() => Ok(Box::new(core::iter::empty())),
326 (Val::Arr(_), Val::Arr(y)) if y.is_empty() => Ok(Box::new(core::iter::empty())),
327 (Val::Str(x), Val::Str(y)) => {
328 let iw = str_windows(x, y.chars().count()).enumerate();
329 Ok(Box::new(iw.filter_map(|(i, w)| (w == **y).then_some(i))))
330 }
331 (Val::Arr(x), Val::Arr(y)) => {
332 let iw = x.windows(y.len()).enumerate();
333 Ok(Box::new(iw.filter_map(|(i, w)| (w == **y).then_some(i))))
334 }
335 (Val::Arr(x), y) => {
336 let ix = x.iter().enumerate();
337 Ok(Box::new(ix.filter_map(move |(i, x)| (x == y).then_some(i))))
338 }
339 (x, y) => Err(Error::index(x.clone(), y.clone())),
340 }
341 }
342}
343
344fn str_windows(line: &str, n: usize) -> impl Iterator<Item = &str> {
348 line.char_indices()
349 .zip(line.char_indices().skip(n).chain(Some((line.len(), ' '))))
350 .map(move |((i, _), (j, _))| &line[i..j])
351}
352
353#[cfg(feature = "parse")]
355pub fn funs() -> impl Iterator<Item = Filter<Native<Val>>> {
356 base_funs().chain([run(parse_fun())])
357}
358
359pub fn base_funs() -> impl Iterator<Item = Filter<Native<Val>>> {
361 base().into_vec().into_iter().map(run)
362}
363
364fn box_once_err<'a>(r: ValR) -> BoxIter<'a, ValX<'a>> {
365 box_once(r.map_err(Exn::from))
366}
367
368fn base() -> Box<[Filter<RunPtr<Val>>]> {
369 Box::new([
370 ("tojson", v(0), |_, cv| {
371 box_once(Ok(cv.1.to_string().into()))
372 }),
373 ("length", v(0), |_, cv| box_once_err(cv.1.length())),
374 ("path_values", v(0), |_, cv| {
375 let pair = |(p, v)| Ok([p, v].into_iter().collect());
376 Box::new(cv.1.path_values(Vec::new()).skip(1).map(pair))
377 }),
378 ("paths", v(0), |_, cv| {
379 Box::new(cv.1.path_values(Vec::new()).skip(1).map(|(p, _v)| Ok(p)))
380 }),
381 ("keys_unsorted", v(0), |_, cv| {
382 let keys = cv.1.key_values().map(|kvs| kvs.map(|(k, _v)| k).collect());
383 let err = || Error::typ(cv.1.clone(), Type::Iter.as_str());
384 box_once_err(keys.ok_or_else(err))
385 }),
386 ("contains", v(1), |_, cv| {
387 unary(cv, |x, y| Ok(Val::from(x.contains(&y))))
388 }),
389 ("has", v(1), |_, cv| {
390 unary(cv, |v, k| v.has(&k).map(Val::from))
391 }),
392 ("indices", v(1), |_, cv| {
393 let to_int = |i: usize| Val::Int(i.try_into().unwrap());
394 unary(cv, move |x, v| {
395 x.indices(&v).map(|idxs| idxs.map(to_int).collect())
396 })
397 }),
398 ])
399}
400
401#[cfg(feature = "parse")]
402fn from_json(s: &str) -> ValR {
404 use hifijson::token::Lex;
405 let mut lexer = hifijson::SliceLexer::new(s.as_bytes());
406 lexer
407 .exactly_one(Val::parse)
408 .map_err(|e| Error::str(format_args!("cannot parse {s} as JSON: {e}")))
409}
410
411#[cfg(feature = "parse")]
412fn parse_fun() -> Filter<RunPtr<Val>> {
413 ("fromjson", v(0), |_, cv| {
414 box_once_err(cv.1.as_str().and_then(|s| from_json(s)))
415 })
416}
417
418fn skip_take(from: usize, until: usize) -> (usize, usize) {
419 (from, until.saturating_sub(from))
420}
421
422fn abs_bound(i: Option<isize>, len: usize, default: usize) -> usize {
425 i.map_or(default, |i| core::cmp::min(wrap(i, len).unwrap_or(0), len))
426}
427
428fn abs_index(i: isize, len: usize) -> Option<usize> {
430 wrap(i, len).filter(|i| *i < len)
431}
432
433fn wrap(i: isize, len: usize) -> Option<usize> {
434 if i >= 0 {
435 Some(i as usize)
436 } else if len < -i as usize {
437 None
438 } else {
439 Some(len - (-i as usize))
440 }
441}
442
443#[test]
444fn wrap_test() {
445 let len = 4;
446 assert_eq!(wrap(0, len), Some(0));
447 assert_eq!(wrap(8, len), Some(8));
448 assert_eq!(wrap(-1, len), Some(3));
449 assert_eq!(wrap(-4, len), Some(0));
450 assert_eq!(wrap(-8, len), None);
451}
452
453impl Val {
454 pub fn obj(m: Map<Rc<String>, Self>) -> Self {
456 Self::Obj(m.into())
457 }
458
459 fn as_int(&self) -> Result<isize, Error> {
461 match self {
462 Self::Int(i) => Ok(*i),
463 _ => Err(Error::typ(self.clone(), Type::Int.as_str())),
464 }
465 }
466
467 fn as_float(&self) -> Result<f64, Error> {
470 match self {
471 Self::Int(n) => Ok(*n as f64),
472 Self::Float(n) => Ok(*n),
473 Self::Num(n) => n
474 .parse()
475 .or(Err(Error::typ(self.clone(), Type::Float.as_str()))),
476 _ => Err(Error::typ(self.clone(), Type::Float.as_str())),
477 }
478 }
479
480 fn into_str(self) -> Result<Rc<String>, Error> {
482 match self {
483 Self::Str(s) => Ok(s),
484 _ => Err(Error::typ(self, Type::Str.as_str())),
485 }
486 }
487
488 #[cfg(feature = "parse")]
489 fn as_str(&self) -> Result<&Rc<String>, Error> {
491 match self {
492 Self::Str(s) => Ok(s),
493 _ => Err(Error::typ(self.clone(), Type::Str.as_str())),
494 }
495 }
496
497 fn into_arr(self) -> Result<Rc<Vec<Self>>, Error> {
499 match self {
500 Self::Arr(a) => Ok(a),
501 _ => Err(Error::typ(self, Type::Arr.as_str())),
502 }
503 }
504
505 fn from_dec_str(n: &str) -> Self {
507 n.parse().map_or(Self::Null, Self::Float)
508 }
509
510 fn has(&self, key: &Self) -> Result<bool, Error> {
514 match (self, key) {
515 (Self::Arr(a), Self::Int(i)) if *i >= 0 => Ok((*i as usize) < a.len()),
516 (Self::Obj(o), Self::Str(s)) => Ok(o.contains_key(&**s)),
517 _ => Err(Error::index(self.clone(), key.clone())),
518 }
519 }
520
521 fn key_values(&self) -> Option<BoxIter<(Val, &Val)>> {
525 let arr_idx = |(i, x)| (Self::Int(i as isize), x);
526 Some(match self {
527 Self::Arr(a) => Box::new(a.iter().enumerate().map(arr_idx)),
528 Self::Obj(o) => Box::new(o.iter().map(|(k, v)| (Self::Str(Rc::clone(k)), v))),
529 _ => return None,
530 })
531 }
532
533 fn path_values<'a>(self, path: Vec<Val>) -> BoxIter<'a, (Val, Val)> {
535 let head = (path.iter().cloned().collect(), self.clone());
536 let f = move |k| path.iter().cloned().chain([k]).collect();
537 let kvs = self.key_values().into_iter().flatten();
538 let kvs: Vec<_> = kvs.map(|(k, v)| (k, v.clone())).collect();
539 let tail = kvs.into_iter().flat_map(move |(k, v)| v.path_values(f(k)));
540 Box::new(core::iter::once(head).chain(tail))
541 }
542
543 fn contains(&self, other: &Self) -> bool {
550 match (self, other) {
551 (Self::Str(l), Self::Str(r)) => l.contains(&**r),
552 (Self::Arr(l), Self::Arr(r)) => r.iter().all(|r| l.iter().any(|l| l.contains(r))),
553 (Self::Obj(l), Self::Obj(r)) => r
554 .iter()
555 .all(|(k, r)| l.get(k).map_or(false, |l| l.contains(r))),
556 _ => self == other,
557 }
558 }
559
560 #[cfg(feature = "hifijson")]
566 pub fn parse(token: Token, lexer: &mut impl LexAlloc) -> Result<Self, hifijson::Error> {
567 use hifijson::{token, Error};
568 match token {
569 Token::Null => Ok(Self::Null),
570 Token::True => Ok(Self::Bool(true)),
571 Token::False => Ok(Self::Bool(false)),
572 Token::DigitOrMinus => {
573 let (num, parts) = lexer.num_string()?;
574 if parts.dot.is_none() && parts.exp.is_none() {
576 if let Ok(i) = num.parse() {
578 return Ok(Self::Int(i));
579 }
580 }
581 Ok(Self::Num(Rc::new(num.to_string())))
582 }
583 Token::Quote => Ok(Self::from(lexer.str_string()?.to_string())),
584 Token::LSquare => Ok(Self::Arr({
585 let mut arr = Vec::new();
586 lexer.seq(Token::RSquare, |token, lexer| {
587 arr.push(Self::parse(token, lexer)?);
588 Ok::<_, hifijson::Error>(())
589 })?;
590 arr.into()
591 })),
592 Token::LCurly => Ok(Self::obj({
593 let mut obj = Map::default();
594 lexer.seq(Token::RCurly, |token, lexer| {
595 let key =
596 lexer.str_colon(token, |lexer| lexer.str_string().map_err(Error::Str))?;
597
598 let token = lexer.ws_token().ok_or(token::Expect::Value)?;
599 let value = Self::parse(token, lexer)?;
600 obj.insert(Rc::new(key.to_string()), value);
601 Ok::<_, Error>(())
602 })?;
603 obj
604 })),
605 _ => Err(token::Expect::Value)?,
606 }
607 }
608}
609
610#[cfg(feature = "serde_json")]
611impl From<serde_json::Value> for Val {
612 fn from(v: serde_json::Value) -> Self {
613 use serde_json::Value::*;
614 match v {
615 Null => Self::Null,
616 Bool(b) => Self::Bool(b),
617 Number(n) => n
618 .to_string()
619 .parse()
620 .map_or_else(|_| Self::Num(Rc::new(n.to_string())), Self::Int),
621 String(s) => Self::from(s),
622 Array(a) => a.into_iter().map(Self::from).collect(),
623 Object(o) => Self::obj(o.into_iter().map(|(k, v)| (Rc::new(k), v.into())).collect()),
624 }
625 }
626}
627
628#[cfg(feature = "serde_json")]
629impl From<Val> for serde_json::Value {
630 fn from(v: Val) -> Self {
631 use core::str::FromStr;
632 use serde_json::Value::*;
633 match v {
634 Val::Null => Null,
635 Val::Bool(b) => Bool(b),
636 Val::Int(i) => Number(i.into()),
637 Val::Float(f) => serde_json::Number::from_f64(f).map_or(Null, Number),
638 Val::Num(n) => Number(serde_json::Number::from_str(&n).unwrap()),
639 Val::Str(s) => String((*s).clone()),
640 Val::Arr(a) => Array(a.iter().map(|x| x.clone().into()).collect()),
641 Val::Obj(o) => Object(
642 o.iter()
643 .map(|(k, v)| ((**k).clone(), v.clone().into()))
644 .collect(),
645 ),
646 }
647 }
648}
649
650impl From<bool> for Val {
651 fn from(b: bool) -> Self {
652 Self::Bool(b)
653 }
654}
655
656impl From<isize> for Val {
657 fn from(i: isize) -> Self {
658 Self::Int(i)
659 }
660}
661
662impl From<f64> for Val {
663 fn from(f: f64) -> Self {
664 Self::Float(f)
665 }
666}
667
668impl From<String> for Val {
669 fn from(s: String) -> Self {
670 Self::Str(Rc::new(s))
671 }
672}
673
674impl FromIterator<Self> for Val {
675 fn from_iter<T: IntoIterator<Item = Self>>(iter: T) -> Self {
676 Self::Arr(Rc::new(iter.into_iter().collect()))
677 }
678}
679
680impl core::ops::Add for Val {
681 type Output = ValR;
682 fn add(self, rhs: Self) -> Self::Output {
683 use Val::*;
684 match (self, rhs) {
685 (Null, x) | (x, Null) => Ok(x),
687 (Int(x), Int(y)) => Ok(Int(x + y)),
688 (Int(i), Float(f)) | (Float(f), Int(i)) => Ok(Float(f + i as f64)),
689 (Float(x), Float(y)) => Ok(Float(x + y)),
690 (Num(n), r) => Self::from_dec_str(&n) + r,
691 (l, Num(n)) => l + Self::from_dec_str(&n),
692 (Str(mut l), Str(r)) => {
693 Rc::make_mut(&mut l).push_str(&r);
694 Ok(Str(l))
695 }
696 (Arr(mut l), Arr(r)) => {
697 Rc::make_mut(&mut l).extend(r.iter().cloned());
699 Ok(Arr(l))
700 }
701 (Obj(mut l), Obj(r)) => {
702 Rc::make_mut(&mut l).extend(r.iter().map(|(k, v)| (k.clone(), v.clone())));
703 Ok(Obj(l))
704 }
705 (l, r) => Err(Error::math(l, ops::Math::Add, r)),
706 }
707 }
708}
709
710impl core::ops::Sub for Val {
711 type Output = ValR;
712 fn sub(self, rhs: Self) -> Self::Output {
713 use Val::*;
714 match (self, rhs) {
715 (Int(x), Int(y)) => Ok(Int(x - y)),
716 (Float(f), Int(i)) => Ok(Float(f - i as f64)),
717 (Int(i), Float(f)) => Ok(Float(i as f64 - f)),
718 (Float(x), Float(y)) => Ok(Float(x - y)),
719 (Num(n), r) => Self::from_dec_str(&n) - r,
720 (l, Num(n)) => l - Self::from_dec_str(&n),
721 (Arr(mut l), Arr(r)) => {
722 let r = r.iter().collect::<alloc::collections::BTreeSet<_>>();
723 Rc::make_mut(&mut l).retain(|x| !r.contains(x));
724 Ok(Arr(l))
725 }
726 (l, r) => Err(Error::math(l, ops::Math::Sub, r)),
727 }
728 }
729}
730
731fn obj_merge(l: &mut Rc<Map<Rc<String>, Val>>, r: Rc<Map<Rc<String>, Val>>) {
732 let l = Rc::make_mut(l);
733 let r = rc_unwrap_or_clone(r).into_iter();
734 r.for_each(|(k, v)| match (l.get_mut(&k), v) {
735 (Some(Val::Obj(l)), Val::Obj(r)) => obj_merge(l, r),
736 (Some(l), r) => *l = r,
737 (None, r) => {
738 l.insert(k, r);
739 }
740 });
741}
742
743impl core::ops::Mul for Val {
744 type Output = ValR;
745 fn mul(self, rhs: Self) -> Self::Output {
746 use Val::*;
747 match (self, rhs) {
748 (Int(x), Int(y)) => Ok(Int(x * y)),
749 (Float(f), Int(i)) | (Int(i), Float(f)) => Ok(Float(f * i as f64)),
750 (Float(x), Float(y)) => Ok(Float(x * y)),
751 (Str(s), Int(i)) | (Int(i), Str(s)) if i > 0 => Ok(Self::from(s.repeat(i as usize))),
752 (Str(_), Int(_)) | (Int(_), Str(_)) => Ok(Null),
755 (Num(n), r) => Self::from_dec_str(&n) * r,
756 (l, Num(n)) => l * Self::from_dec_str(&n),
757 (Obj(mut l), Obj(r)) => {
758 obj_merge(&mut l, r);
759 Ok(Obj(l))
760 }
761 (l, r) => Err(Error::math(l, ops::Math::Mul, r)),
762 }
763 }
764}
765
766fn split<'a>(s: &'a str, sep: &'a str) -> Box<dyn Iterator<Item = String> + 'a> {
768 if s.is_empty() {
769 Box::new(core::iter::empty())
770 } else if sep.is_empty() {
771 Box::new(s.chars().map(|s| s.to_string()))
775 } else {
776 Box::new(s.split(sep).map(|s| s.to_string()))
777 }
778}
779
780impl core::ops::Div for Val {
781 type Output = ValR;
782 fn div(self, rhs: Self) -> Self::Output {
783 use Val::{Float, Int, Num, Str};
784 match (self, rhs) {
785 (Int(x), Int(y)) => Ok(Float(x as f64 / y as f64)),
786 (Float(f), Int(i)) => Ok(Float(f / i as f64)),
787 (Int(i), Float(f)) => Ok(Float(i as f64 / f)),
788 (Float(x), Float(y)) => Ok(Float(x / y)),
789 (Num(n), r) => Self::from_dec_str(&n) / r,
790 (l, Num(n)) => l / Self::from_dec_str(&n),
791 (Str(x), Str(y)) => Ok(split(&x, &y).map(Val::from).collect()),
792 (l, r) => Err(Error::math(l, ops::Math::Div, r)),
793 }
794 }
795}
796
797impl core::ops::Rem for Val {
798 type Output = ValR;
799 fn rem(self, rhs: Self) -> Self::Output {
800 use Val::{Float, Int, Num};
801 match (self, rhs) {
802 (Int(x), Int(y)) if y != 0 => Ok(Int(x % y)),
803 (Float(f), Int(i)) => Ok(Float(f % i as f64)),
804 (Int(i), Float(f)) => Ok(Float(i as f64 % f)),
805 (Float(x), Float(y)) => Ok(Float(x % y)),
806 (Num(n), r) => Self::from_dec_str(&n) % r,
807 (l, Num(n)) => l % Self::from_dec_str(&n),
808 (l, r) => Err(Error::math(l, ops::Math::Rem, r)),
809 }
810 }
811}
812
813impl core::ops::Neg for Val {
814 type Output = ValR;
815 fn neg(self) -> Self::Output {
816 use Val::*;
817 match self {
818 Int(x) => Ok(Int(-x)),
819 Float(x) => Ok(Float(-x)),
820 Num(n) => -Self::from_dec_str(&n),
821 x => Err(Error::typ(x, Type::Num.as_str())),
822 }
823 }
824}
825
826impl PartialEq for Val {
827 fn eq(&self, other: &Self) -> bool {
828 match (self, other) {
829 (Self::Null, Self::Null) => true,
830 (Self::Bool(x), Self::Bool(y)) => x == y,
831 (Self::Int(x), Self::Int(y)) => x == y,
832 (Self::Int(i), Self::Float(f)) | (Self::Float(f), Self::Int(i)) => {
833 float_eq(*i as f64, *f)
834 }
835 (Self::Float(x), Self::Float(y)) => float_eq(*x, *y),
836 (Self::Num(x), Self::Num(y)) if Rc::ptr_eq(x, y) => true,
837 (Self::Num(n), y) => &Self::from_dec_str(n) == y,
838 (x, Self::Num(n)) => x == &Self::from_dec_str(n),
839 (Self::Str(x), Self::Str(y)) => x == y,
840 (Self::Arr(x), Self::Arr(y)) => x == y,
841 (Self::Obj(x), Self::Obj(y)) => x == y,
842 _ => false,
843 }
844 }
845}
846
847impl Eq for Val {}
848
849impl PartialOrd for Val {
850 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
851 Some(self.cmp(other))
852 }
853}
854
855impl Ord for Val {
856 fn cmp(&self, other: &Self) -> Ordering {
857 use Ordering::{Equal, Greater, Less};
858 match (self, other) {
859 (Self::Null, Self::Null) => Equal,
860 (Self::Bool(x), Self::Bool(y)) => x.cmp(y),
861 (Self::Int(x), Self::Int(y)) => x.cmp(y),
862 (Self::Int(i), Self::Float(f)) => float_cmp(*i as f64, *f),
863 (Self::Float(f), Self::Int(i)) => float_cmp(*f, *i as f64),
864 (Self::Float(x), Self::Float(y)) => float_cmp(*x, *y),
865 (Self::Num(x), Self::Num(y)) if Rc::ptr_eq(x, y) => Equal,
866 (Self::Num(n), y) => Self::from_dec_str(n).cmp(y),
867 (x, Self::Num(n)) => x.cmp(&Self::from_dec_str(n)),
868 (Self::Str(x), Self::Str(y)) => x.cmp(y),
869 (Self::Arr(x), Self::Arr(y)) => x.cmp(y),
870 (Self::Obj(x), Self::Obj(y)) => match (x.len(), y.len()) {
871 (0, 0) => Equal,
872 (0, _) => Less,
873 (_, 0) => Greater,
874 _ => {
875 let mut l: Vec<_> = x.iter().collect();
876 let mut r: Vec<_> = y.iter().collect();
877 l.sort_by_key(|(k, _v)| *k);
878 r.sort_by_key(|(k, _v)| *k);
879 let kl = l.iter().map(|(k, _v)| k);
881 let kr = r.iter().map(|(k, _v)| k);
882 let vl = l.iter().map(|(_k, v)| v);
883 let vr = r.iter().map(|(_k, v)| v);
884 kl.cmp(kr).then_with(|| vl.cmp(vr))
885 }
886 },
887
888 (Self::Null, _) => Less,
890 (_, Self::Null) => Greater,
891 (Self::Bool(_), _) => Less,
893 (_, Self::Bool(_)) => Greater,
894 (Self::Int(_) | Self::Float(_), _) => Less,
896 (_, Self::Int(_) | Self::Float(_)) => Greater,
897 (Self::Str(_), _) => Less,
899 (_, Self::Str(_)) => Greater,
900 (Self::Arr(_), _) => Less,
901 (_, Self::Arr(_)) => Greater,
902 }
903 }
904}
905
906fn float_eq(left: f64, right: f64) -> bool {
907 float_cmp(left, right) == Ordering::Equal
908}
909
910fn float_cmp(left: f64, right: f64) -> Ordering {
911 if left == 0. && right == 0. {
912 Ordering::Equal
914 } else if left.is_nan() {
915 Ordering::Less
920 } else if right.is_nan() {
921 Ordering::Greater
922 } else {
923 f64::total_cmp(&left, &right)
924 }
925}
926
927pub fn fmt_str(f: &mut fmt::Formatter, s: &str) -> fmt::Result {
929 write!(f, "\"")?;
930 for s in s.split_inclusive(|c| c < ' ' || c == '\\' || c == '"') {
931 let mut chars = s.chars();
933 let last = chars.next_back();
934 let init = chars.as_str();
935
936 match last {
937 Some(last @ ('\t' | '\n' | '\r' | '\\' | '"')) => {
938 write!(f, "{init}{}", last.escape_default())
939 }
940 Some(last) if last < ' ' => write!(f, "{init}\\u{:04x}", last as u8),
941 _ => write!(f, "{s}"),
942 }?;
943 }
944 write!(f, "\"")
945}
946
947impl fmt::Display for Val {
948 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
949 match self {
950 Self::Null => write!(f, "null"),
951 Self::Bool(b) => write!(f, "{b}"),
952 Self::Int(i) => write!(f, "{i}"),
953 Self::Float(x) if x.is_finite() => write!(f, "{x:?}"),
954 Self::Float(_) => write!(f, "null"),
955 Self::Num(n) => write!(f, "{n}"),
956 Self::Str(s) => fmt_str(f, s),
957 Self::Arr(a) => {
958 write!(f, "[")?;
959 let mut iter = a.iter();
960 if let Some(first) = iter.next() {
961 write!(f, "{first}")?;
962 };
963 iter.try_for_each(|x| write!(f, ",{x}"))?;
964 write!(f, "]")
965 }
966 Self::Obj(o) => {
967 write!(f, "{{")?;
968 let mut iter = o.iter().map(|(k, v)| (Val::Str(k.clone()), v));
969 if let Some((k, v)) = iter.next() {
970 write!(f, "{k}:{v}")?;
971 }
972 iter.try_for_each(|(k, v)| write!(f, ",{k}:{v}"))?;
973 write!(f, "}}")
974 }
975 }
976 }
977}