Skip to content

Commit 9d35443

Browse files
committed
Add jaq support
1 parent 8d90393 commit 9d35443

3 files changed

Lines changed: 282 additions & 0 deletions

File tree

Cargo.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,9 @@ hex = "0.4"
1616
clap = { version = "4.5", features = ["derive"] }
1717
simple_logger = { version = "5.0", features = ["stderr"], optional = true }
1818
serde = { version = "1.0.219", features = ["derive"], optional = true }
19+
jaq-all = { git = "https://github.com/01mf02/jaq", version = "0.1.0-alpha" }
20+
# FIXME: remove this after jaq support is complete
21+
fn_name = "0.1.0"
1922

2023
[dev-dependencies]
2124
assert_cmd = "2.0"

src/jaq.rs

Lines changed: 278 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,278 @@
1+
use std::{cmp::Ordering, collections::BTreeMap, ops::{Add, Div, Mul, Neg, Rem, Sub}};
2+
3+
use jaq_all::jaq_core::{Error, ops};
4+
5+
use crate::{RpcValue, Value};
6+
7+
pub type ValR = jaq_all::jaq_core::ValR<RpcValue>;
8+
pub type ValX = jaq_all::jaq_core::ValX<RpcValue>;
9+
impl Neg for RpcValue {
10+
type Output = ValR;
11+
fn neg(self) -> Self::Output {
12+
match &self.value {
13+
Value::Int(num) => Ok((-num).into()),
14+
_ => Err(jaq_all::jaq_core::Error::typ(self, "")),
15+
}
16+
}
17+
}
18+
19+
impl Add for RpcValue {
20+
type Output = ValR;
21+
fn add(self, rhs: Self) -> Self::Output {
22+
match (&self.value, &rhs.value) {
23+
(Value::Int(x), Value::Int(y)) => Ok((x + y).into()),
24+
(Value::UInt(x), Value::UInt(y)) => Ok((x + y).into()),
25+
_=> Err(Error::math(self, ops::Math::Div, rhs))
26+
}
27+
}
28+
}
29+
30+
impl Sub for RpcValue {
31+
type Output = ValR;
32+
fn sub(self, rhs: Self) -> Self::Output {
33+
match (&self.value, &rhs.value) {
34+
(Value::Int(x), Value::Int(y)) => Ok((x - y).into()),
35+
(Value::UInt(x), Value::UInt(y)) => Ok((x - y).into()),
36+
_=> Err(Error::math(self, ops::Math::Div, rhs))
37+
}
38+
}
39+
}
40+
41+
impl Mul for RpcValue {
42+
type Output = ValR;
43+
fn mul(self, rhs: Self) -> Self::Output {
44+
match (&self.value, &rhs.value) {
45+
(Value::Int(x), Value::Int(y)) => Ok((x * y).into()),
46+
_=> Err(Error::math(self, ops::Math::Div, rhs))
47+
}
48+
}
49+
}
50+
51+
impl Div for RpcValue {
52+
type Output = ValR;
53+
fn div(self, rhs: Self) -> Self::Output {
54+
match (&self.value, &rhs.value) {
55+
(Value::Int(x), Value::Int(y)) => Ok((x / y).into()),
56+
_=> Err(Error::math(self, ops::Math::Div, rhs))
57+
}
58+
}
59+
}
60+
61+
impl Rem for RpcValue {
62+
type Output = ValR;
63+
fn rem(self, rhs: Self) -> Self::Output {
64+
match (&self.value, &rhs.value) {
65+
(Value::Int(x), Value::Int(y)) => Ok((x % y).into()),
66+
_=> Err(Error::math(self, ops::Math::Div, rhs))
67+
}
68+
}
69+
}
70+
71+
impl PartialOrd for RpcValue {
72+
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
73+
Some(self.cmp(other))
74+
}
75+
}
76+
impl Eq for RpcValue {}
77+
78+
impl Ord for RpcValue {
79+
fn cmp(&self, other: &Self) -> std::cmp::Ordering {
80+
use Ordering::{Equal, Greater, Less};
81+
match (&self.value, &other.value) {
82+
(Value::Bool(x), Value::Bool(y)) => x.cmp(y),
83+
(Value::Int(x), Value::Int(y)) => x.cmp(y),
84+
(Value::UInt(x), Value::UInt(y)) => x.cmp(y),
85+
(Value::DateTime(x), Value::DateTime(y)) => x.cmp(y),
86+
(Value::Decimal(x), Value::Decimal(y)) => todo!("{}", fn_name::uninstantiated!()),
87+
(Value::String(x), Value::String(y)) => x.cmp(y),
88+
(Value::Blob(x), Value::Blob(y)) => x.cmp(y),
89+
(Value::List(x), Value::List(y)) => x.cmp(y),
90+
(Value::Map(x), Value::Map(y)) => x.cmp(y),
91+
(Value::IMap(x), Value::IMap(y)) => x.cmp(y),
92+
(Value::Null, Value::Null) => Equal,
93+
(Value::Null, _) => Less,
94+
(_, Value::Null) => Greater,
95+
(Value::Bool(_), _) => Less,
96+
(_, Value::Bool(_)) => Greater,
97+
(Value::Int(_), _) => Less,
98+
(_, Value::Int(_)) => Greater,
99+
(Value::UInt(_), _) => Less,
100+
(_, Value::UInt(_)) => Greater,
101+
(Value::Double(_), _) => Less,
102+
(_, Value::Double(_)) => Greater,
103+
(Value::Decimal(_), _) => Less,
104+
(_, Value::Decimal(_)) => Greater,
105+
(Value::DateTime(_), _) => Less,
106+
(_, Value::DateTime(_)) => Greater,
107+
(Value::String(_), _) => Less,
108+
(_, Value::String(_)) => Greater,
109+
(Value::Blob(_), _) => Less,
110+
(_, Value::Blob(_)) => Greater,
111+
(Value::List(_), _) => Less,
112+
(_, Value::List(_)) => Greater,
113+
(Value::IMap(_), _) => Less,
114+
(_, Value::IMap(_)) => Greater,
115+
}
116+
}
117+
}
118+
119+
impl FromIterator<RpcValue> for RpcValue {
120+
fn from_iter<T: IntoIterator<Item = RpcValue>>(iter: T) -> Self {
121+
iter.into_iter().collect::<Vec<_>>().into()
122+
}
123+
}
124+
125+
impl From<core::ops::Range<Option<RpcValue>>> for RpcValue {
126+
fn from(value: core::ops::Range<Option<RpcValue>>) -> Self {
127+
let kv = |(k, v): (&str, Option<_>)| v.map(|v| (k.to_owned().into(), v));
128+
let kvs = [("start", value.start), ("end", value.end)];
129+
kvs.into_iter().flat_map(kv).collect::<BTreeMap<String,_>>().into()
130+
}
131+
}
132+
133+
impl From<usize> for RpcValue {
134+
fn from(value: usize) -> Self {
135+
value.into()
136+
}
137+
}
138+
139+
impl jaq_all::jaq_std::ValT for RpcValue {
140+
fn into_seq<S: FromIterator<Self>>(self) -> Result<S, Self> {
141+
match self.value {
142+
Value::List(list) => Ok(list.into_iter().collect()),
143+
_ => Err(self)
144+
}
145+
}
146+
147+
fn is_int(&self) -> bool {
148+
self.is_int()
149+
}
150+
151+
fn as_isize(&self) -> Option<isize> {
152+
match self.value {
153+
Value::Int(num) => Some(num as isize),
154+
_ => None,
155+
}
156+
}
157+
158+
fn as_f64(&self) -> Option<f64> {
159+
todo!("{}", fn_name::uninstantiated!());
160+
}
161+
162+
fn is_utf8_str(&self) -> bool {
163+
todo!("{}", fn_name::uninstantiated!());
164+
}
165+
166+
fn as_bytes(&self) -> Option<&[u8]> {
167+
todo!("{}", fn_name::uninstantiated!());
168+
}
169+
170+
fn as_sub_str(&self, sub: &[u8]) -> Self {
171+
todo!("{}", fn_name::uninstantiated!());
172+
}
173+
174+
fn from_utf8_bytes(b: impl AsRef<[u8]> + Send + 'static) -> Self {
175+
todo!("{}", fn_name::uninstantiated!());
176+
}
177+
}
178+
179+
impl jaq_all::jaq_core::ValT for RpcValue {
180+
fn from_num(n: &str) -> ValR {
181+
Ok(i64::from_str_radix(n, 10).map(RpcValue::from).unwrap_or(0_i64.into()))
182+
}
183+
184+
fn from_map<I: IntoIterator<Item = (Self, Self)>>(iter: I) -> ValR {
185+
Ok(iter.into_iter().map(|(k, v)| (k.as_str().to_owned(), v)).collect::<BTreeMap<String, _>>().into())
186+
}
187+
188+
fn key_values(self) -> jaq_all::jaq_core::box_iter::BoxIter<'static, jaq_all::jaq_core::ValR<(Self, Self), Self>> {
189+
match self.value {
190+
Value::List(list) => {
191+
Box::new(list
192+
.into_iter()
193+
.enumerate()
194+
.map(|(idx, val)| Ok((RpcValue::from(idx as isize), val))))
195+
}
196+
Value::Map(map) => {
197+
Box::new(map
198+
.into_iter()
199+
.map(|(key, val)| Ok((RpcValue::from(key), val))))
200+
}
201+
Value::IMap(map) => {
202+
Box::new(map
203+
.into_iter()
204+
.map(|(key, val)| Ok((RpcValue::from(key), val))))
205+
}
206+
_ => Box::new(Err(Error::typ(self, "iterable (List or Map or IMap)")).into_iter())
207+
}
208+
}
209+
210+
fn values(self) -> Box<dyn Iterator<Item = ValR>> {
211+
match self.value {
212+
Value::List(list) => {
213+
Box::new(list
214+
.into_iter()
215+
.map(|val| Ok(val)))
216+
}
217+
Value::Map(map) => {
218+
Box::new(map
219+
.into_values()
220+
.map(|val| Ok(val)))
221+
}
222+
Value::IMap(map) => {
223+
Box::new(map
224+
.into_values()
225+
.map(|val| Ok(val)))
226+
}
227+
_ => Box::new(Err(Error::typ(self, "iterable (List or Map or IMap)")).into_iter())
228+
}
229+
}
230+
231+
fn index(self, index: &Self) -> ValR {
232+
match (&self.value, &index.value) {
233+
(Value::Null, _) => Ok(RpcValue::null()),
234+
(Value::String(rv), Value::Int(i)) => Ok(rv.chars().nth(*i as usize).map(|cha| cha.to_string()).into()),
235+
(Value::List(list), Value::Int(i)) => Ok((*list).get(*i as usize).cloned().unwrap_or(RpcValue::null())),
236+
(Value::Map(o), Value::String(key)) => Ok(o.get(key.as_str()).cloned().unwrap_or(RpcValue::null())),
237+
(s, _) => Err(Error::typ(self, "")),
238+
}
239+
}
240+
241+
fn range(self, range: jaq_all::jaq_core::val::Range<&Self>) -> ValR {
242+
todo!("{}", fn_name::uninstantiated!());
243+
}
244+
245+
fn map_values<I: Iterator<Item = ValX>>(
246+
self,
247+
opt: jaq_all::jaq_core::path::Opt,
248+
f: impl Fn(Self) -> I,
249+
) -> ValX {
250+
todo!("{}", fn_name::uninstantiated!());
251+
}
252+
253+
fn map_index<I: Iterator<Item = ValX>>(
254+
self,
255+
index: &Self,
256+
opt: jaq_all::jaq_core::path::Opt,
257+
f: impl Fn(Self) -> I,
258+
) -> ValX {
259+
todo!("{}", fn_name::uninstantiated!());
260+
}
261+
262+
fn map_range<I: Iterator<Item = ValX>>(
263+
self,
264+
range: jaq_all::jaq_core::val::Range<&Self>,
265+
opt: jaq_all::jaq_core::path::Opt,
266+
f: impl Fn(Self) -> I,
267+
) -> ValX {
268+
todo!("{}", fn_name::uninstantiated!());
269+
}
270+
271+
fn as_bool(&self) -> bool {
272+
self.as_bool()
273+
}
274+
275+
fn into_string(self) -> Self {
276+
self.to_cpon().into()
277+
}
278+
}

src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
pub mod chainpack;
44
pub mod cpon;
5+
pub mod jaq;
56
pub mod json;
67
pub mod datetime;
78
pub mod decimal;

0 commit comments

Comments
 (0)