aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGuillaume Pasquet <dev@etenil.net>2022-02-21 00:18:38 +0000
committerGuillaume Pasquet <dev@etenil.net>2022-02-21 00:18:38 +0000
commit883b9c65fce7f8596b7da5616efab8c4ecc616a4 (patch)
tree538ec099430b9e83577b3849a509d924cd3f97ec
parentf69d2801069850b48c6424b50d0107799d56e2f8 (diff)
Added support for JQ filtering.
-rw-r--r--Cargo.lock25
-rw-r--r--Cargo.toml1
-rw-r--r--src/barbfile.rs46
-rw-r--r--src/executor.rs4
-rw-r--r--src/main.rs26
-rw-r--r--test-filter.barb5
6 files changed, 80 insertions, 27 deletions
diff --git a/Cargo.lock b/Cargo.lock
index ede2199..33100d5 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -39,6 +39,7 @@ name = "barb"
version = "0.1.3"
dependencies = [
"clap 3.0.14",
+ "jq-rs",
"jsonformat",
"serde",
"serde_json",
@@ -206,6 +207,24 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1aab8fc367588b89dcee83ab0fd66b72b50b72fa1904d7095045ace2b0c81c35"
[[package]]
+name = "jq-rs"
+version = "0.4.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c9cfaeae42ef96b227ab787558cc7bbd5f1dfe96b4df7c63f92853017751b0e4"
+dependencies = [
+ "jq-sys",
+]
+
+[[package]]
+name = "jq-sys"
+version = "0.2.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "81b65b7e54bd2fffc8cb20cbcf19f40d3158dab5cf5b5adb1f65f9b35eba4c48"
+dependencies = [
+ "pkg-config",
+]
+
+[[package]]
name = "js-sys"
version = "0.3.56"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -288,6 +307,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e"
[[package]]
+name = "pkg-config"
+version = "0.3.24"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "58893f751c9b0412871a09abd62ecd2a00298c6c83befa223ef98c52aef40cbe"
+
+[[package]]
name = "proc-macro-error"
version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
diff --git a/Cargo.toml b/Cargo.toml
index 68d51da..11373f5 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -17,3 +17,4 @@ clap = { version = "3.0.14", features = ["derive"] }
serde = "1.0.130"
serde_json = "1.0.70"
jsonformat = "1.2.0"
+jq-rs = "0.4.1"
diff --git a/src/barbfile.rs b/src/barbfile.rs
index 1a17796..19a24cd 100644
--- a/src/barbfile.rs
+++ b/src/barbfile.rs
@@ -80,16 +80,16 @@ impl Header {
}
}
-struct BarbHeader {
+struct BarbPreamble {
pub method: Method,
pub url: String,
pub headers: Vec<Header>,
pub filter: Option<String>,
}
-impl BarbHeader {
+impl BarbPreamble {
fn new(method: Method, url: String, headers: Vec<Header>, filter: Option<String>) -> Self {
- BarbHeader {
+ BarbPreamble {
method: method,
url: url,
headers: headers,
@@ -99,25 +99,29 @@ impl BarbHeader {
}
pub struct BarbFile {
- header: BarbHeader,
+ preamble: BarbPreamble,
body: Option<String>,
}
impl BarbFile {
pub fn headers(&self) -> &Vec<Header> {
- &self.header.headers
+ &self.preamble.headers
}
pub fn method(&self) -> &Method {
- &self.header.method
+ &self.preamble.method
}
pub fn method_as_string(&self) -> String {
- self.header.method.to_string()
+ self.preamble.method.to_string()
}
pub fn url(&self) -> &String {
- &self.header.url
+ &self.preamble.url
+ }
+
+ pub fn filter(&self) -> &Option<String> {
+ &self.preamble.filter
}
pub fn body(&self) -> &Option<String> {
@@ -172,7 +176,7 @@ impl FromStr for BarbFile {
let body = lines.fold(String::from(""), |acc, x| acc + x);
Ok(BarbFile {
- header: BarbHeader::new(method, url, headers, filter),
+ preamble: BarbPreamble::new(method, url, headers, filter),
body: if body == "" { None } else { Some(body) },
})
}
@@ -214,12 +218,12 @@ mod tests {
let barbfile =
BarbFile::from_str("#GET^https://blah.com/api/blah\n#Authorization: BLAH\n#|filtr\n")
.unwrap();
- assert!(matches!(barbfile.header.method, Method::GET));
- assert_eq!(barbfile.header.url, "https://blah.com/api/blah");
- assert_eq!(barbfile.header.filter, Some(String::from("filtr")));
- assert_eq!(barbfile.header.headers.len(), 1);
- assert_eq!(barbfile.header.headers[0].name, "Authorization");
- assert_eq!(barbfile.header.headers[0].value, "BLAH");
+ assert!(matches!(barbfile.preamble.method, Method::GET));
+ assert_eq!(barbfile.preamble.url, "https://blah.com/api/blah");
+ assert_eq!(barbfile.preamble.filter, Some(String::from("filtr")));
+ assert_eq!(barbfile.preamble.headers.len(), 1);
+ assert_eq!(barbfile.preamble.headers[0].name, "Authorization");
+ assert_eq!(barbfile.preamble.headers[0].value, "BLAH");
assert_eq!(barbfile.body, None);
}
@@ -228,12 +232,12 @@ mod tests {
let barbfile =
BarbFile::from_str("#POST^https://blah.com/api/blah\n#Authorization: BLAH\n#|filtr\n\n{\"key\":\"value\"}\n")
.unwrap();
- assert!(matches!(barbfile.header.method, Method::POST));
- assert_eq!(barbfile.header.url, "https://blah.com/api/blah");
- assert_eq!(barbfile.header.filter, Some(String::from("filtr")));
- assert_eq!(barbfile.header.headers.len(), 1);
- assert_eq!(barbfile.header.headers[0].name, "Authorization");
- assert_eq!(barbfile.header.headers[0].value, "BLAH");
+ assert!(matches!(barbfile.preamble.method, Method::POST));
+ assert_eq!(barbfile.preamble.url, "https://blah.com/api/blah");
+ assert_eq!(barbfile.preamble.filter, Some(String::from("filtr")));
+ assert_eq!(barbfile.preamble.headers.len(), 1);
+ assert_eq!(barbfile.preamble.headers[0].name, "Authorization");
+ assert_eq!(barbfile.preamble.headers[0].value, "BLAH");
assert_eq!(barbfile.body, Some(String::from("{\"key\":\"value\"}")))
}
}
diff --git a/src/executor.rs b/src/executor.rs
index 4930c5f..bd9767b 100644
--- a/src/executor.rs
+++ b/src/executor.rs
@@ -95,8 +95,8 @@ impl Executor {
}
}
- pub fn execute(&mut self, bfile: BarbFile, print_headers: bool) -> Result<ureq::Response, String> {
- self.run(&bfile, self.make_req(&bfile, print_headers))
+ pub fn execute(&mut self, bfile: &BarbFile, print_headers: bool) -> Result<ureq::Response, String> {
+ self.run(bfile, self.make_req(&bfile, print_headers))
}
}
diff --git a/src/main.rs b/src/main.rs
index f3891ad..a35ad7d 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -1,6 +1,7 @@
mod barbfile;
mod executor;
+use jq_rs;
use jsonformat::{format_json, Indentation};
use std::slice::Iter;
@@ -24,6 +25,8 @@ struct Args {
body: bool,
#[clap(short, long)]
raw: bool,
+ #[clap(short, long)]
+ filter: Option<String>,
files: Vec<String>,
}
@@ -48,6 +51,20 @@ impl Args {
{
self.files.iter()
}
+
+ pub fn jq_filter(&self) -> &Option<String>
+ {
+ &self.filter
+ }
+}
+
+fn apply_filters(args: &Args, bfile: &BarbFile, body: String) -> Result<String, String> {
+ if let Some(filter) = args.jq_filter() {
+ return Ok(jq_rs::run(filter.as_str(), body.as_str()).map_err(|x| x.to_string())?);
+ } else if let Some(filter) = bfile.filter() {
+ return Ok(jq_rs::run(filter.as_str(), body.as_str()).map_err(|x| x.to_string())?);
+ }
+ Ok(String::from(body))
}
fn run_file(args: &Args, executor: &mut Executor, file_name: &String) -> Result<(), String> {
@@ -56,7 +73,7 @@ fn run_file(args: &Args, executor: &mut Executor, file_name: &String) -> Result<
.map_err(|_| format!("Failed to read file '{}'", file_name))?
.as_str(),
).map_err(|_| format!("Failed to parse file '{}'", file_name))?;
- let response = executor.execute(bfile, args.req_headers())?;
+ let response = executor.execute(&bfile, args.req_headers())?;
if args.print_headers() {
println!("{} {}", response.status(), response.status_text());
@@ -71,12 +88,13 @@ fn run_file(args: &Args, executor: &mut Executor, file_name: &String) -> Result<
}
if args.print_body() {
+ let body = apply_filters(args, &bfile, response.into_string().unwrap())?;
println!(
"{}",
match args.raw_body() {
- true => String::from(response.into_string().unwrap().as_str()),
+ true => body,
false => format_json(
- response.into_string().unwrap().as_str(),
+ body.as_str(),
Indentation::Default
),
}
@@ -92,7 +110,7 @@ fn main() {
let mut executor = Executor::new(Context::new(env::vars()));
for file in args.files_iter() {
- match run_file(&args, &mut executor, &file) {
+ match run_file(&args, &mut executor, file) {
Ok(()) => (),
Err(err) => println!("{}", err)
}
diff --git a/test-filter.barb b/test-filter.barb
new file mode 100644
index 0000000..28a9955
--- /dev/null
+++ b/test-filter.barb
@@ -0,0 +1,5 @@
+#GET^https://catfact.ninja/fact
+#Foo: Bar
+#Baz: {TERM}
+#|.fact
+