jaq_core/val.rs
1//! Values that can be processed by jaq.
2//!
3//! To process your own value type with jaq,
4//! you need to implement the [`ValT`] trait.
5
6use crate::box_iter::BoxIter;
7use crate::path::Opt;
8use core::fmt::Display;
9use core::ops::{Add, Div, Mul, Neg, Rem, Sub};
10
11// Makes `f64::from_str` accessible as intra-doc link.
12#[cfg(doc)]
13use core::str::FromStr;
14
15/// Value or eRror.
16pub type ValR<T, V = T> = Result<T, crate::Error<V>>;
17/// Stream of values and eRrors.
18pub type ValRs<'a, T, V = T> = BoxIter<'a, ValR<T, V>>;
19/// Value or eXception.
20///
21/// Use [`unwrap_valr`] to convert to [`ValR`].
22pub type ValX<'a, T, V = T> = Result<T, crate::Exn<'a, V>>;
23/// Stream of values and eXceptions.
24pub type ValXs<'a, T, V = T> = BoxIter<'a, ValX<'a, T, V>>;
25
26/// Convert a value exception [`ValX`] into a value result [`ValR`].
27///
28/// This should always succeed when called on results of a main filter.
29/// For any other filter, this may not succeed, i.e. panic.
30///
31/// If you are writing a native filter, e.g. `f(f1; ...; fn)`,
32/// do not use this function on outputs of `fi`!
33///
34/// This function will exit the current process if
35/// the value exception results from a call to the filter `halt`.
36/// If the `std` feature is disabled, this function panics instead.
37/// In a future jaq 3.0, this function should only be provided if
38/// the `std` feature is enabled.
39pub fn unwrap_valr<T, V>(v: ValX<T, V>) -> ValR<T, V> {
40 #[cfg(feature = "std")]
41 let exit = |exit_code| std::process::exit(exit_code);
42 #[cfg(not(feature = "std"))]
43 let exit = |exit_code| panic!("halt({})", exit_code);
44
45 let halt = |e: crate::Exn<_>| exit(e.get_halt().ok().unwrap());
46 v.map_err(|e| e.get_err().unwrap_or_else(halt))
47}
48
49/// Range of options, used for iteration operations.
50pub type Range<V> = core::ops::Range<Option<V>>;
51
52/// Values that can be processed by jaq.
53///
54/// Implement this trait if you want jaq to process your own type of values.
55pub trait ValT:
56 Clone
57 + Display
58 + From<bool>
59 + From<isize>
60 + From<alloc::string::String>
61 + From<Range<Self>>
62 + FromIterator<Self>
63 + PartialEq
64 + PartialOrd
65 + Add<Output = ValR<Self>>
66 + Sub<Output = ValR<Self>>
67 + Mul<Output = ValR<Self>>
68 + Div<Output = ValR<Self>>
69 + Rem<Output = ValR<Self>>
70 + Neg<Output = ValR<Self>>
71{
72 /// Create a number from a string.
73 ///
74 /// The number should adhere to the format accepted by [`f64::from_str`].
75 fn from_num(n: &str) -> ValR<Self>;
76
77 /// Create an associative map (or object) from a sequence of key-value pairs.
78 ///
79 /// This is used when creating values with the syntax `{k: v}`.
80 fn from_map<I: IntoIterator<Item = (Self, Self)>>(iter: I) -> ValR<Self>;
81
82 /// Yield the key-value pairs of a value.
83 ///
84 /// This is used to collect the paths of `.[]`.
85 /// It should yield any `key` for which `value | .[key]` is defined,
86 /// as well as its output.
87 fn key_values(self) -> BoxIter<'static, ValR<(Self, Self), Self>>;
88
89 /// Yield the children of a value.
90 ///
91 /// This is used by `.[]`.
92 fn values(self) -> alloc::boxed::Box<dyn Iterator<Item = ValR<Self>>>;
93
94 /// Yield the child of a value at the given index.
95 ///
96 /// This is used by `.[k]`.
97 ///
98 /// If `v.index(k)` is `Ok(_)`, then it is contained in `v.values()`.
99 fn index(self, index: &Self) -> ValR<Self>;
100
101 /// Yield a slice of the value with the given range.
102 ///
103 /// This is used by `.[s:e]`, `.[s:]`, and `.[:e]`.
104 fn range(self, range: Range<&Self>) -> ValR<Self>;
105
106 /// Map a function over the children of the value.
107 ///
108 /// This is used by
109 /// - `.[] |= f` (`opt` = [`Opt::Essential`]) and
110 /// - `.[]? |= f` (`opt` = [`Opt::Optional`]).
111 ///
112 /// If the children of the value are undefined, then:
113 ///
114 /// - If `opt` is [`Opt::Essential`], return an error.
115 /// - If `opt` is [`Opt::Optional`] , return the input value.
116 fn map_values<'a, I: Iterator<Item = ValX<'a, Self>>>(
117 self,
118 opt: Opt,
119 f: impl Fn(Self) -> I,
120 ) -> ValX<'a, Self>;
121
122 /// Map a function over the child of the value at the given index.
123 ///
124 /// This is used by `.[k] |= f`.
125 ///
126 /// See [`Self::map_values`] for the behaviour of `opt`.
127 fn map_index<'a, I: Iterator<Item = ValX<'a, Self>>>(
128 self,
129 index: &Self,
130 opt: Opt,
131 f: impl Fn(Self) -> I,
132 ) -> ValX<'a, Self>;
133
134 /// Map a function over the slice of the value with the given range.
135 ///
136 /// This is used by `.[s:e] |= f`, `.[s:] |= f`, and `.[:e] |= f`.
137 ///
138 /// See [`Self::map_values`] for the behaviour of `opt`.
139 fn map_range<'a, I: Iterator<Item = ValX<'a, Self>>>(
140 self,
141 range: Range<&Self>,
142 opt: Opt,
143 f: impl Fn(Self) -> I,
144 ) -> ValX<'a, Self>;
145
146 /// Return a boolean representation of the value.
147 ///
148 /// This is used by `if v then ...`.
149 fn as_bool(&self) -> bool;
150
151 /// Convert value into a string value.
152 ///
153 /// This is used by `"\(v)"`.
154 fn into_string(self) -> Self;
155}