aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGuillaume Pasquet <dev@etenil.net>2022-02-24 23:19:51 +0000
committerGuillaume Pasquet <dev@etenil.net>2022-02-24 23:19:51 +0000
commit30dd79ca9480ddb9db19030113d14ede49272411 (patch)
tree821fa5904e992e2086642a2a33dba16d8c49df66
parent79a577031c062a4e3f79f39c8d18ea7edb8a425e (diff)
Fix #4: Color output
-rw-r--r--.gitlab-ci.yml3
-rw-r--r--Cargo.lock12
-rw-r--r--Cargo.toml1
-rw-r--r--src/executor.rs31
-rw-r--r--src/main.rs68
-rw-r--r--src/output.rs104
-rw-r--r--test_api/test_api_get.barb1
7 files changed, 157 insertions, 63 deletions
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index f406606..de5d876 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -9,7 +9,8 @@ variables:
test:
stage: test
script:
- - cargo test --all --verbose
+ - apt install libjq1 libjq-dev libonig-dev libonig5
+ - JQ_LIB_DIR=/usr/lib/x86_64-linux-gnu cargo test --all --verbose
# pretty:
# stage: test
diff --git a/Cargo.lock b/Cargo.lock
index 0057543..2bcbd21 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -39,6 +39,7 @@ name = "barb"
version = "0.1.5"
dependencies = [
"clap 3.0.14",
+ "colored",
"jq-rs",
"jsonformat",
"serde",
@@ -128,6 +129,17 @@ dependencies = [
]
[[package]]
+name = "colored"
+version = "2.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b3616f750b84d8f0de8a58bda93e08e2a81ad3f523089b05f1dffecab48c6cbd"
+dependencies = [
+ "atty",
+ "lazy_static",
+ "winapi",
+]
+
+[[package]]
name = "crc32fast"
version = "1.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
diff --git a/Cargo.toml b/Cargo.toml
index 09bd918..5ae0756 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -18,3 +18,4 @@ serde = "1.0.130"
serde_json = "1.0.70"
jsonformat = "1.2.0"
jq-rs = "0.4.1"
+colored = "2.0.0"
diff --git a/src/executor.rs b/src/executor.rs
index bd948b5..40a2857 100644
--- a/src/executor.rs
+++ b/src/executor.rs
@@ -1,9 +1,11 @@
use crate::barbfile::BarbFile;
+use crate::output::BarbOutput;
use std::collections::HashMap;
use ureq;
use ureq::Error as UreqError;
+
pub struct Context {
vars: HashMap<String, String>,
}
@@ -57,32 +59,24 @@ impl Executor {
Executor { context }
}
- fn make_req(&self, bfile: &BarbFile, print_req: bool, print_headers: bool) -> ureq::Request {
- if print_req {
- println!(
- "{} {}",
- bfile.method_as_string().as_str(),
- self.context.substitute(&bfile.url()).as_str()
- );
- }
+ fn make_req(&self, bfile: &BarbFile, output: &BarbOutput) -> ureq::Request {
+ output.req(bfile.method_as_string(), self.context.substitute(&bfile.url()));
let mut req = ureq::request(
bfile.method_as_string().as_str(),
self.context.substitute(&bfile.url()).as_str(),
);
for header in bfile.headers() {
+ let hdr_val = self.context.substitute(header.value());
req = req.set(
header.name(),
- self.context.substitute(header.value()).as_str(),
+ hdr_val.as_str(),
);
- if print_headers {
- println!(
- "{} {}",
- header.name(),
- self.context.substitute(header.value())
- );
- }
+ output.req_hdr(header.name().to_string(), hdr_val);
}
+
+ output.end_req();
+
req
}
@@ -105,10 +99,9 @@ impl Executor {
pub fn execute(
&mut self,
bfile: &BarbFile,
- print_req: bool,
- print_headers: bool,
+ output: &BarbOutput,
) -> Result<ureq::Response, String> {
- self.run(bfile, self.make_req(&bfile, print_req, print_headers))
+ self.run(bfile, self.make_req(&bfile, output))
}
}
diff --git a/src/main.rs b/src/main.rs
index 6099020..a02938a 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -1,12 +1,13 @@
mod barbfile;
mod executor;
+mod output;
use jq_rs;
-use jsonformat::{format_json, Indentation};
use std::slice::Iter;
use barbfile::BarbFile;
use executor::{Context, Executor};
+use output::BarbOutput;
use clap::Parser;
@@ -27,30 +28,14 @@ struct Args {
raw: bool,
#[clap(short, long)]
filter: Option<String>,
+ #[clap(short, long)]
+ path: Option<String>,
+ #[clap(short, long)]
+ no_color: bool,
files: Vec<String>,
}
impl Args {
- pub fn print_req(&self) -> bool {
- return !self.body
- }
-
- pub fn print_headers(&self) -> bool {
- self.headers || self.all_headers || !self.body
- }
-
- pub fn print_body(&self) -> bool {
- !self.headers || self.body
- }
-
- pub fn raw_body(&self) -> bool {
- self.raw
- }
-
- pub fn req_headers(&self) -> bool {
- self.all_headers
- }
-
pub fn files_iter(&self) -> Iter<String> {
self.files.iter()
}
@@ -58,6 +43,17 @@ impl Args {
pub fn jq_filter(&self) -> &Option<String> {
&self.filter
}
+
+ pub fn output(&self) -> BarbOutput {
+ BarbOutput::new(
+ !self.body,
+ self.all_headers,
+ self.headers || self.all_headers || !self.body,
+ !self.headers || self.body,
+ self.raw,
+ !self.no_color,
+ )
+ }
}
fn apply_filters(args: &Args, bfile: &BarbFile, body: String) -> Result<String, String> {
@@ -76,30 +72,16 @@ fn run_file(args: &Args, executor: &mut Executor, file_name: &String) -> Result<
.as_str(),
)
.map_err(|_| format!("Failed to parse file '{}'", file_name))?;
- let response = executor.execute(&bfile, args.print_req(), args.req_headers())?;
-
- if args.print_headers() {
- println!("{} {}", response.status(), response.status_text());
- for header_name in response.headers_names() {
- println!(
- "{}: {}",
- header_name,
- // Header is guaranteed to exist
- response.header(header_name.as_str()).unwrap()
- );
- }
- }
+ let output = args.output();
+ let response = executor.execute(&bfile, &output)?;
- if args.print_body() {
- let body = apply_filters(args, &bfile, response.into_string().unwrap())?;
- println!(
- "{}",
- match args.raw_body() {
- true => body,
- false => format_json(body.as_str(), Indentation::Default),
- }
- );
+ output.status(response.status(), response.status_text());
+ for header_name in response.headers_names() {
+ output.resp_hdr(header_name.to_string(), response.header(header_name.as_str()).unwrap());
}
+ output.end_resp_hdr();
+
+ output.body(apply_filters(args, &bfile, response.into_string().unwrap())?);
Ok(())
}
diff --git a/src/output.rs b/src/output.rs
new file mode 100644
index 0000000..d181d0f
--- /dev/null
+++ b/src/output.rs
@@ -0,0 +1,104 @@
+use colored::*;
+use jsonformat::{format_json, Indentation};
+use std::fmt::Display;
+
+pub struct BarbOutput {
+ request: bool,
+ req_headers: bool,
+ headers: bool,
+ body: bool,
+ raw_body: bool,
+ color: bool,
+}
+
+impl BarbOutput {
+ fn _print_header<T, I>(&self, name: T, value: I)
+ where T: Display, I: Display{
+ println!("{}: {}", name, value);
+ }
+
+ pub fn new(request: bool, req_headers: bool, headers: bool, body: bool, raw_body: bool, color: bool) -> BarbOutput {
+ BarbOutput {
+ request,
+ req_headers,
+ headers,
+ body,
+ raw_body,
+ color,
+ }
+ }
+
+ pub fn req(&self, method: String, url: String) {
+ if !self.request {
+ return;
+ }
+ if self.color {
+ println!("{} {}", method.purple(), url.purple());
+ } else {
+ println!("{} {}", method, url);
+ }
+ }
+
+ pub fn req_hdr(&self, name: String, value: String) {
+ if !self.req_headers {
+ return;
+ }
+ if self.color {
+ self._print_header(name.yellow(), value);
+ } else {
+ self._print_header(name, value);
+ }
+ }
+
+ pub fn end_req(&self) {
+ if self.req_headers || self.request {
+ println!("");
+ }
+ }
+
+ pub fn resp_hdr(&self, name: String, value: &str) {
+ if !self.headers {
+ return;
+ }
+ if self.color {
+ self._print_header(name.blue(), value);
+ } else {
+ self._print_header(name, value);
+ }
+ }
+
+ pub fn end_resp_hdr(&self) {
+ if self.headers {
+ println!("");
+ }
+ }
+
+ pub fn status(&self, code: u16, text: &str) {
+ if !self.headers {
+ return;
+ }
+ if self.color {
+ if code >= 400 {
+ println!("{} {}", code.to_string().red(), text.red());
+ } else {
+ println!("{} {}", code.to_string().green(), text);
+ }
+ } else {
+ println!("{} {}", code, text);
+ }
+ }
+
+ pub fn body(&self, body: String) {
+ if !self.body {
+ return;
+ }
+
+ println!(
+ "{}",
+ match self.raw_body {
+ true => body,
+ false => format_json(body.as_str(), Indentation::Default),
+ }
+ );
+ }
+}
diff --git a/test_api/test_api_get.barb b/test_api/test_api_get.barb
index 6bdf592..9746f24 100644
--- a/test_api/test_api_get.barb
+++ b/test_api/test_api_get.barb
@@ -1 +1,2 @@
#GET^http://localhost:8080/
+#Foo: Bar