Skip to content

Commit 5cdd930

Browse files
committed
Implement more jaq
1 parent e0699f1 commit 5cdd930

2 files changed

Lines changed: 59 additions & 15 deletions

File tree

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ name = "shvproto"
55
description = "Rust implementation of the SHV protocol"
66
license = "MIT"
77
repository = "https://github.com/silicon-heaven/libshvproto-rs"
8-
version = "5.0.0"
8+
version = "5.0.1"
99
edition = "2024"
1010

1111
[dependencies]

src/jaq.rs

Lines changed: 58 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -157,23 +157,38 @@ impl jaq_all::jaq_std::ValT for RpcValue {
157157
}
158158

159159
fn as_f64(&self) -> Option<f64> {
160-
todo!("{}", fn_name::uninstantiated!());
160+
if let Value::Double(double) = self.value {
161+
Some(double)
162+
} else {
163+
None
164+
}
161165
}
162166

163167
fn is_utf8_str(&self) -> bool {
164-
todo!("{}", fn_name::uninstantiated!());
168+
self.is_string()
165169
}
166170

167171
fn as_bytes(&self) -> Option<&[u8]> {
168-
todo!("{}", fn_name::uninstantiated!());
172+
if let Value::String(str) = &self.value {
173+
Some(str.as_bytes())
174+
} else {
175+
None
176+
}
169177
}
170178

171-
fn as_sub_str(&self, _sub: &[u8]) -> Self {
172-
todo!("{}", fn_name::uninstantiated!());
179+
fn as_sub_str(&self, sub: &[u8]) -> Self {
180+
if matches!(&self.value, Value::String(_)) {
181+
// We do not have any fancy bytes handling, so we will just believe that the sub range
182+
// is a substring of self, and create a string out of it.
183+
String::from_utf8_lossy(sub).to_string().into()
184+
} else {
185+
// jaq-json panics here, but I don't really like that, so if self is not a String, let's just give null.
186+
RpcValue::null()
187+
}
173188
}
174189

175-
fn from_utf8_bytes(_b: impl AsRef<[u8]> + Send + 'static) -> Self {
176-
todo!("{}", fn_name::uninstantiated!());
190+
fn from_utf8_bytes(b: impl AsRef<[u8]> + Send + 'static) -> Self {
191+
String::from_utf8_lossy(b.as_ref()).to_string().into()
177192
}
178193
}
179194

@@ -241,16 +256,45 @@ impl jaq_all::jaq_core::ValT for RpcValue {
241256
}
242257
}
243258

244-
fn range(self, _range: jaq_all::jaq_core::val::Range<&Self>) -> ValR {
245-
todo!("{}", fn_name::uninstantiated!());
259+
fn range(self, range: jaq_all::jaq_core::val::Range<&Self>) -> ValR {
260+
let start = range.start.map_or(0, RpcValue::as_usize);
261+
let end = range.end.map_or(0, RpcValue::as_usize);
262+
match &self.value {
263+
Value::String(str) => {
264+
let bytes = str.as_bytes();
265+
bytes.get(start..end).map(|bytes| String::from_utf8_lossy(bytes).to_string().into()).ok_or_else(|| Error::typ(self, ".."))
266+
}
267+
Value::List(lst) => {
268+
lst
269+
.get(start..end)
270+
.map(|new_range| new_range.to_vec().into())
271+
.ok_or_else(|| Error::typ(self, ".."))
272+
}
273+
_ => Err(Error::typ(self, "")),
274+
}
246275
}
247276

248-
fn map_values<I: Iterator<Item = ValX>>(
249-
self,
250-
_opt: jaq_all::jaq_core::path::Opt,
251-
_f: impl Fn(Self) -> I,
277+
fn map_values<I: Iterator<Item = ValX>>(self, opt: jaq_all::jaq_core::path::Opt, f: impl Fn(Self) -> I,
252278
) -> ValX {
253-
todo!("{}", fn_name::uninstantiated!());
279+
match self.value {
280+
Value::List(lst) => {
281+
lst
282+
.into_iter()
283+
.flat_map(f)
284+
.collect::<Result<Vec<_>,_>>()
285+
.map(Into::into)
286+
}
287+
Value::Map(map) => {
288+
map
289+
.into_iter()
290+
.filter_map(|(k, v)| f(v)
291+
.next()
292+
.map(|v| Ok((k, v?))))
293+
.collect::<Result<BTreeMap<_,_>,_>>()
294+
.map(Into::into)
295+
}
296+
v => opt.fail(RpcValue { meta: None, value: v }, |v| jaq_all::jaq_core::Exn::from(Error::typ(v, ""))),
297+
}
254298
}
255299

256300
fn map_index<I: Iterator<Item = ValX>>(

0 commit comments

Comments
 (0)