From cd99572fa2c6088b240ed8651ed27fa960044b7b Mon Sep 17 00:00:00 2001 From: alemi Date: Sat, 19 Oct 2024 20:18:34 +0200 Subject: [PATCH] feat: add JQL and Regex extractors --- Cargo.lock | 90 +++++++++++++++++++++++++++++++++++++++--- Cargo.toml | 1 + src/errors.rs | 6 +++ src/model/endpoint.rs | 20 +++++++++- src/model/extractor.rs | 4 +- 5 files changed, 112 insertions(+), 9 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 3619b4a..e78df81 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -238,6 +238,37 @@ version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e496a50fda8aacccc86d7529e2c1e0892dbd0f898a6b5645b5561b89c3210efa" +[[package]] +name = "crossbeam-deque" +version = "0.8.5" +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" + [[package]] name = "encoding_rs" version = "0.8.32" @@ -559,6 +590,7 @@ checksum = "707907fe3c25f5424cce2cb7e1cbcafee6bdbe735ca90ef77c29e84591e5b9da" dependencies = [ "equivalent", "hashbrown", + "rayon", "serde", ] @@ -600,6 +632,29 @@ version = "1.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "453ad9f582a441959e5f0d088b02ce04cfe8d51a8eaf077f12ac6d3e94164ca6" +[[package]] +name = "jql-parser" +version = "7.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc6c5d45258356a8b4ff8265b929cc95880be34fdc34c884e0ab4585d4a3f356" +dependencies = [ + "thiserror", + "winnow", +] + +[[package]] +name = "jql-runner" +version = "7.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26d68343315f3a2668bf340993d0ae2686bed277d2fb74b28a083fc50fd1db44" +dependencies = [ + "indexmap", + "jql-parser", + "rayon", + "serde_json", + "thiserror", +] + [[package]] name = "js-sys" version = "0.3.72" @@ -818,6 +873,7 @@ dependencies = [ "clap", "http", "indexmap", + "jql-runner", "regex", "reqwest", "serde", @@ -846,6 +902,26 @@ 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" @@ -1047,18 +1123,18 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.164" +version = "1.0.210" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e8c8cf938e98f769bc164923b06dce91cea1751522f46f8466461af04c9027d" +checksum = "c8e3592472072e6e22e0a54d5904d9febf8508f65fb8552499a1abc7d1078c3a" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.164" +version = "1.0.210" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9735b638ccc51c28bf6914d90a2e9725b377144fc612c49a611fddd1b631d68" +checksum = "243902eda00fad750862fc144cea25caca5e20d615af0a81bee94ca738f1df1f" dependencies = [ "proc-macro2", "quote", @@ -1067,11 +1143,13 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.97" +version = "1.0.132" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bdf3bf93142acad5821c99197022e170842cdbc1c30482b98750c688c640842a" +checksum = "d726bfaff4b320266d395898905d0eba0345aae23b54aee3a737e260fd46db03" dependencies = [ + "indexmap", "itoa", + "memchr", "ryu", "serde", ] diff --git a/Cargo.toml b/Cargo.toml index 0d281a7..7699b05 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,6 +11,7 @@ chrono = "0.4" clap = { version = "4.5", features = ["derive"] } http = "1.1.0" indexmap = { version = "2.6", features = ["serde"] } +jql-runner = "7.2" regex = "1.11" reqwest = { version = "0.12", features = ["json"] } serde = { version = "1.0", features = ["derive"] } diff --git a/src/errors.rs b/src/errors.rs index fa814c2..47aab33 100644 --- a/src/errors.rs +++ b/src/errors.rs @@ -36,4 +36,10 @@ pub enum PostWomanError { #[error("invalid regex: {0:?}")] InvalidRegex(#[from] regex::Error), + + #[error("invalid JQL query: {0:?}")] + JQLError(#[from] jql_runner::errors::JqlRunnerError), + + #[error("regex failed matching in content: {0}")] + NoMatch(String), } diff --git a/src/model/endpoint.rs b/src/model/endpoint.rs index 61d5589..595bbd7 100644 --- a/src/model/endpoint.rs +++ b/src/model/endpoint.rs @@ -128,8 +128,13 @@ impl Endpoint { Ok(match self.extract.unwrap_or_default() { StringOr::Str(_query) => todo!(), StringOr::T(Extractor::Discard) => "".to_string(), - StringOr::T(Extractor::Debug) => format!("{res:#?}\nBody: ") + &format_body(res).await? + "\n", // ughhh StringOr::T(Extractor::Body) => format_body(res).await?, + StringOr::T(Extractor::Debug) => { + // TODO needless double format + let res_dbg = format!("{res:#?}"); + let body = format_body(res).await?; + format!("{res_dbg}\nBody: {body}\n") + }, StringOr::T(Extractor::Header { key }) => res .headers() .get(&key) @@ -137,6 +142,19 @@ impl Endpoint { .to_str()? .to_string() + "\n", + StringOr::T(Extractor::Jql { query }) => { + let json: serde_json::Value = res.json().await?; + let selection = jql_runner::runner::raw(&query, &json)?; + serde_json::to_string_pretty(&selection)? + }, + StringOr::T(Extractor::Regex { pattern }) => { + let pattern = regex::Regex::new(&pattern)?; + let body = format_body(res).await?; + pattern.find(&body) + .ok_or_else(|| PostWomanError::NoMatch(body.clone()))? + .as_str() + .to_string() + }, }) } } diff --git a/src/model/extractor.rs b/src/model/extractor.rs index ef51233..c46c209 100644 --- a/src/model/extractor.rs +++ b/src/model/extractor.rs @@ -6,7 +6,7 @@ pub enum Extractor { Debug, Body, Discard, - // JQL { query: String }, - // Regex { pattern: String }, + Jql { query: String }, + Regex { pattern: String }, Header { key: String }, }