chore: swap JQL for JAQ: it's more similar to jq

This commit is contained in:
əlemi 2024-10-19 21:44:05 +02:00
parent 81661bb136
commit 6211a1630e
Signed by: alemi
GPG key ID: A4895B84D311642C
5 changed files with 152 additions and 75 deletions

165
Cargo.lock generated
View file

@ -17,6 +17,19 @@ version = "2.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627"
[[package]]
name = "ahash"
version = "0.8.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011"
dependencies = [
"cfg-if",
"getrandom",
"once_cell",
"version_check",
"zerocopy",
]
[[package]]
name = "aho-corasick"
version = "1.0.2"
@ -26,6 +39,12 @@ dependencies = [
"memchr",
]
[[package]]
name = "allocator-api2"
version = "0.2.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5c6cb57a04249c6480766f7f7cef5467412af1490f8d1e243141daddada3264f"
[[package]]
name = "android-tzdata"
version = "0.1.1"
@ -176,6 +195,15 @@ dependencies = [
"windows-targets 0.52.6",
]
[[package]]
name = "chumsky"
version = "0.9.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8eebd66744a15ded14960ab4ccdbfb51ad3b81f51f3f04a80adac98c985396c9"
dependencies = [
"hashbrown 0.14.5",
]
[[package]]
name = "clap"
version = "4.5.20"
@ -239,35 +267,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e496a50fda8aacccc86d7529e2c1e0892dbd0f898a6b5645b5561b89c3210efa"
[[package]]
name = "crossbeam-deque"
version = "0.8.5"
name = "dyn-clone"
version = "1.0.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "613f8cc01fe9cf1a3eb3d7f488fd2fa8388403e97039e2f73692932e291a770d"
dependencies = [
"crossbeam-epoch",
"crossbeam-utils",
]
[[package]]
name = "crossbeam-epoch"
version = "0.9.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e"
dependencies = [
"crossbeam-utils",
]
[[package]]
name = "crossbeam-utils"
version = "0.8.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "22ec99545bb0ed0ea7bb9b8e1e9122ea386ff8a48c0922e43f36d45ab09e0e80"
[[package]]
name = "either"
version = "1.13.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0"
checksum = "0d6ef0072f8a535281e4876be788938b528e9a1d43900b82c2569af7da799125"
[[package]]
name = "encoding_rs"
@ -419,6 +422,16 @@ dependencies = [
"tracing",
]
[[package]]
name = "hashbrown"
version = "0.14.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1"
dependencies = [
"ahash",
"allocator-api2",
]
[[package]]
name = "hashbrown"
version = "0.15.0"
@ -437,6 +450,12 @@ version = "0.3.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024"
[[package]]
name = "hifijson"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9958ab3ce3170c061a27679916bd9b969eceeb5e8b120438e6751d0987655c42"
[[package]]
name = "http"
version = "1.1.0"
@ -589,8 +608,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "707907fe3c25f5424cce2cb7e1cbcafee6bdbe735ca90ef77c29e84591e5b9da"
dependencies = [
"equivalent",
"hashbrown",
"rayon",
"hashbrown 0.15.0",
"serde",
]
@ -633,26 +651,37 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "453ad9f582a441959e5f0d088b02ce04cfe8d51a8eaf077f12ac6d3e94164ca6"
[[package]]
name = "jql-parser"
version = "7.2.0"
name = "jaq-interpret"
version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dc6c5d45258356a8b4ff8265b929cc95880be34fdc34c884e0ab4585d4a3f356"
checksum = "2fe95ec3c24af3fd9f3dd1091593f5e49b003a66c496a8aa39d764d0a06ae17b"
dependencies = [
"thiserror",
"winnow",
"ahash",
"dyn-clone",
"hifijson",
"indexmap",
"jaq-syn",
"once_cell",
"serde_json",
]
[[package]]
name = "jql-runner"
version = "7.2.0"
name = "jaq-parse"
version = "1.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "26d68343315f3a2668bf340993d0ae2686bed277d2fb74b28a083fc50fd1db44"
checksum = "0346d7d3146cdda8acd929581f3d6626a332356c74d5c95aeaffaac2eb6dee82"
dependencies = [
"indexmap",
"jql-parser",
"rayon",
"serde_json",
"thiserror",
"chumsky",
"jaq-syn",
]
[[package]]
name = "jaq-syn"
version = "1.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1ba44fe4428c71304604261ecbae047ee9cfb60c4f1a6bd222ebbb31726d3948"
dependencies = [
"serde",
]
[[package]]
@ -873,7 +902,8 @@ dependencies = [
"clap",
"http",
"indexmap",
"jql-runner",
"jaq-interpret",
"jaq-parse",
"regex",
"reqwest",
"serde",
@ -902,26 +932,6 @@ dependencies = [
"proc-macro2",
]
[[package]]
name = "rayon"
version = "1.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b418a60154510ca1a002a752ca9714984e21e4241e804d32555251faf8b78ffa"
dependencies = [
"either",
"rayon-core",
]
[[package]]
name = "rayon-core"
version = "1.12.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1465873a3dfdaa8ae7cb14b4383657caab0b3e8a0aa9ae8e04b044854c8dfce2"
dependencies = [
"crossbeam-deque",
"crossbeam-utils",
]
[[package]]
name = "redox_syscall"
version = "0.3.5"
@ -1147,7 +1157,6 @@ version = "1.0.132"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d726bfaff4b320266d395898905d0eba0345aae23b54aee3a737e260fd46db03"
dependencies = [
"indexmap",
"itoa",
"memchr",
"ryu",
@ -1504,6 +1513,12 @@ version = "0.2.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426"
[[package]]
name = "version_check"
version = "0.9.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a"
[[package]]
name = "want"
version = "0.3.1"
@ -1840,6 +1855,26 @@ dependencies = [
"memchr",
]
[[package]]
name = "zerocopy"
version = "0.7.35"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0"
dependencies = [
"zerocopy-derive",
]
[[package]]
name = "zerocopy-derive"
version = "0.7.35"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "zeroize"
version = "1.8.1"

View file

@ -11,7 +11,8 @@ chrono = "0.4"
clap = { version = "4.5", features = ["derive"] }
http = "1.1.0"
indexmap = { version = "2.6", features = ["serde"] }
jql-runner = "7.2"
jaq-interpret = "1.5"
jaq-parse = "1.0.3"
regex = "1.11"
reqwest = { version = "0.12", features = ["json"] }
serde = { version = "1.0", features = ["derive"] }

View file

@ -23,7 +23,7 @@ query = [
"cache=0"
]
body = { hello = "world!", success = true }
extract = { type = "body" }
extract = { type = "jql", query = ".path" }
[route.payload]
url = "https://api.alemi.dev/debug"

View file

@ -37,8 +37,8 @@ pub enum PostWomanError {
#[error("invalid regex: {0:?}")]
InvalidRegex(#[from] regex::Error),
#[error("invalid JQL query: {0:?}")]
JQLError(#[from] jql_runner::errors::JqlRunnerError),
#[error("invalid Json Query: {0}")]
JQError(String),
#[error("regex failed matching in content: {0}")]
NoMatch(String),

View file

@ -2,6 +2,7 @@ use std::{collections::HashMap, str::FromStr};
use base64::{prelude::BASE64_STANDARD, Engine};
use http::{HeaderMap, HeaderName, HeaderValue};
use jaq_interpret::FilterT;
use crate::{PostWomanError, APP_USER_AGENT};
@ -49,7 +50,7 @@ fn replace_recursive(element: toml::Value, from: &str, to: &str) -> toml::Value
}
}
fn stringify(v: &toml::Value) -> String {
fn stringify_toml(v: &toml::Value) -> String {
match v {
toml::Value::Boolean(x) => x.to_string(),
toml::Value::Integer(x) => x.to_string(),
@ -61,11 +62,26 @@ fn stringify(v: &toml::Value) -> String {
}
}
fn stringify_json(v: &serde_json::Value) -> String {
match v {
serde_json::Value::Null => "null".to_string(),
serde_json::Value::Bool(x) => x.to_string(),
serde_json::Value::Number(x) => x.to_string(),
serde_json::Value::String(x) => x.clone(),
serde_json::Value::Array(x) => serde_json::to_string(&x).unwrap_or_default(),
serde_json::Value::Object(x) => serde_json::to_string(&x).unwrap_or_default(),
}
}
impl Endpoint {
pub fn fill(mut self, env: &toml::Table) -> Self {
let mut vars: HashMap<String, String> = env.into_iter()
.map(|(k, v)| (k.clone(), stringify(v)))
.collect();
let mut vars: HashMap<String, String> = HashMap::default();
vars.insert("POSTWOMAN_TIMESTAMP".to_string(), chrono::Local::now().timestamp().to_string());
for (k, v) in env {
vars.insert(k.to_string(), stringify_toml(v));
}
for (k, v) in std::env::vars() {
vars.insert(k, v);
@ -172,8 +188,12 @@ impl Endpoint {
// bare string defaults to JQL query
StringOr::T(Extractor::Jql { query }) | StringOr::Str(query) => {
let json: serde_json::Value = res.json().await?;
let selection = jql_runner::runner::raw(&query, &json)?;
serde_json::to_string_pretty(&selection)?
let selection = jq(&query, json)?;
if selection.len() == 1 {
stringify_json(&selection[0]) + "\n"
} else {
serde_json::to_string_pretty(&selection)? + "\n"
}
},
})
}
@ -189,3 +209,24 @@ async fn format_body(res: reqwest::Response) -> Result<String, PostWomanError> {
},
}
}
fn jq(query: &str, value: serde_json::Value) -> Result<Vec<serde_json::Value>, PostWomanError> {
// TODO am i not getting jaq api? or is it just this weird????
let mut defs = jaq_interpret::ParseCtx::new(Vec::new());
let (filter, errs) = jaq_parse::parse(query, jaq_parse::main());
let Some(filter) = filter else {
return Err(PostWomanError::JQError(
errs.into_iter().map(|x| format!("{x:?}")).collect::<Vec<String>>().join(", ")
));
};
let out: Vec<serde_json::Value> = defs
.compile(filter)
.run((
jaq_interpret::Ctx::new([], &jaq_interpret::RcIter::new(core::iter::empty())),
jaq_interpret::Val::from(value)
))
.filter_map(|x| Some(x.ok()?.into()))
.collect();
Ok(out)
}