63 lines
1.4 KiB
Rust
63 lines
1.4 KiB
Rust
use std::{fs::File, io::Read, iter::once};
|
|
|
|
use jaq_interpret::{Error, Native, ParseCtx, Val};
|
|
use tracing::{debug, error, trace};
|
|
|
|
use super::macros::*;
|
|
|
|
pub fn load(jaq: &mut ParseCtx) {
|
|
trace!("jaq: add hash filter");
|
|
jaq.insert_native(
|
|
"hash".into(),
|
|
0,
|
|
Native::new({
|
|
move |_, (_, val)| {
|
|
let string = match &val {
|
|
Val::Str(v) => v.to_string(),
|
|
_ => return_err!(Err(Error::str("expected string but got {val:?}"))),
|
|
};
|
|
|
|
Box::new(once(Ok(Val::Str(
|
|
blake3::hash(string.as_bytes()).to_hex().to_string().into(),
|
|
))))
|
|
}
|
|
}),
|
|
);
|
|
|
|
trace!("jaq: add file_hash filter");
|
|
jaq.insert_native(
|
|
"file_hash".into(),
|
|
0,
|
|
Native::new({
|
|
move |_, (_, val)| {
|
|
let path = match &val {
|
|
Val::Str(v) => v.to_string(),
|
|
_ => return_err!(Err(Error::str("expected string but got {val:?}"))),
|
|
};
|
|
|
|
Box::new(once(Ok(match File::open(&path) {
|
|
Ok(mut file) => {
|
|
const BUFFER_SIZE: usize = 1024 * 1024;
|
|
let mut hasher = blake3::Hasher::new();
|
|
let mut buf = vec![0; BUFFER_SIZE];
|
|
while let Ok(bytes) = file.read(&mut buf) {
|
|
debug!("jaq: read {bytes} bytes from {path:?}");
|
|
if bytes == 0 {
|
|
break;
|
|
}
|
|
hasher.update(&buf[..bytes]);
|
|
buf = vec![0; BUFFER_SIZE];
|
|
}
|
|
|
|
Val::Str(hasher.finalize().to_hex().to_string().into())
|
|
}
|
|
Err(err) => {
|
|
error!("jaq: failed to open file {path:?}: {err:?}");
|
|
Val::Null
|
|
}
|
|
})))
|
|
}
|
|
}),
|
|
);
|
|
}
|