feat: handle errors instead of bubbling everything
also fix by-value/by-reference stuff
This commit is contained in:
parent
37e6c48048
commit
1ac3301779
1 changed files with 29 additions and 16 deletions
45
src/main.rs
45
src/main.rs
|
@ -58,8 +58,9 @@ pub enum PostWomanActions {
|
||||||
|
|
||||||
const TIMESTAMP_FMT: &str = "%H:%M:%S%.6f";
|
const TIMESTAMP_FMT: &str = "%H:%M:%S%.6f";
|
||||||
|
|
||||||
fn main() -> Result<(), PostWomanError> {
|
fn main() {
|
||||||
let args = PostWomanArgs::parse();
|
let args = PostWomanArgs::parse();
|
||||||
|
let multi_thread = args.multi_threaded;
|
||||||
|
|
||||||
// if we got a regex, test it early to avoid wasting work when invalid
|
// if we got a regex, test it early to avoid wasting work when invalid
|
||||||
if let Some(PostWomanActions::Run { ref query, .. }) = args.action {
|
if let Some(PostWomanActions::Run { ref query, .. }) = args.action {
|
||||||
|
@ -71,13 +72,14 @@ fn main() -> Result<(), PostWomanError> {
|
||||||
|
|
||||||
load_collections(&mut collections, args.collection.clone());
|
load_collections(&mut collections, args.collection.clone());
|
||||||
|
|
||||||
if args.multi_threaded {
|
|
||||||
let task = async move {
|
let task = async move {
|
||||||
|
|
||||||
for (name, collection) in collections {
|
for (name, collection) in collections {
|
||||||
run_postwoman(&args, name, collection).await;
|
run_postwoman(&args, name, collection).await;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if multi_thread {
|
||||||
tokio::runtime::Builder::new_multi_thread()
|
tokio::runtime::Builder::new_multi_thread()
|
||||||
.enable_all()
|
.enable_all()
|
||||||
.build()
|
.build()
|
||||||
|
@ -110,10 +112,14 @@ fn load_collections(store: &mut HashMap<String, PostWomanCollection>, mut path:
|
||||||
store.insert(name, collection);
|
store.insert(name, collection);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const DEFAULT_ACTION: PostWomanActions = PostWomanActions::List { verbose: false };
|
||||||
|
|
||||||
|
async fn run_postwoman(args: &PostWomanArgs, name: String, collection: PostWomanCollection) {
|
||||||
|
let action = args.action.as_ref().unwrap_or(&DEFAULT_ACTION);
|
||||||
|
|
||||||
match action {
|
match action {
|
||||||
PostWomanActions::List { verbose } => {
|
PostWomanActions::List { verbose } => {
|
||||||
let ua = collection.client.user_agent.unwrap_or(APP_USER_AGENT.to_string());
|
println!("> {name}");
|
||||||
println!("> {ua}");
|
|
||||||
|
|
||||||
for (key, value) in collection.env {
|
for (key, value) in collection.env {
|
||||||
println!("+ {key}: {}", ext::stringify_toml(&value));
|
println!("+ {key}: {}", ext::stringify_toml(&value));
|
||||||
|
@ -123,7 +129,7 @@ fn load_collections(store: &mut HashMap<String, PostWomanCollection>, mut path:
|
||||||
|
|
||||||
for (name, mut endpoint) in collection.route {
|
for (name, mut endpoint) in collection.route {
|
||||||
println!("- {name}: \t{} \t{}", endpoint.method.as_deref().unwrap_or("GET"), endpoint.url);
|
println!("- {name}: \t{} \t{}", endpoint.method.as_deref().unwrap_or("GET"), endpoint.url);
|
||||||
if verbose {
|
if *verbose {
|
||||||
if let Some(ref query) = endpoint.query {
|
if let Some(ref query) = endpoint.query {
|
||||||
for query in query {
|
for query in query {
|
||||||
println!(" |? {query}");
|
println!(" |? {query}");
|
||||||
|
@ -145,15 +151,16 @@ fn load_collections(store: &mut HashMap<String, PostWomanCollection>, mut path:
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
PostWomanActions::Run { query, parallel, repeat, debug } => {
|
PostWomanActions::Run { query, parallel, repeat, debug } => {
|
||||||
let pattern = regex::Regex::new(&query)?;
|
// this is always safe to compile because we tested it beforehand
|
||||||
|
let pattern = regex::Regex::new(query).expect("tested it before and still failed here???");
|
||||||
let mut joinset = tokio::task::JoinSet::new();
|
let mut joinset = tokio::task::JoinSet::new();
|
||||||
let client = std::sync::Arc::new(collection.client);
|
let client = std::sync::Arc::new(collection.client);
|
||||||
let env = std::sync::Arc::new(collection.env);
|
let env = std::sync::Arc::new(collection.env);
|
||||||
for (name, mut endpoint) in collection.route {
|
for (name, mut endpoint) in collection.route {
|
||||||
if pattern.find(&name).is_some() {
|
if pattern.find(&name).is_some() {
|
||||||
if debug { endpoint.extract = Some(ext::StringOr::T(model::ExtractorConfig::Debug)) };
|
if *debug { endpoint.extract = Some(ext::StringOr::T(model::ExtractorConfig::Debug)) };
|
||||||
for i in 0..repeat {
|
for i in 0..*repeat {
|
||||||
let suffix = if repeat > 1 {
|
let suffix = if *repeat > 1 {
|
||||||
format!("#{} ", i+1)
|
format!("#{} ", i+1)
|
||||||
} else {
|
} else {
|
||||||
"".to_string()
|
"".to_string()
|
||||||
|
@ -171,31 +178,37 @@ fn load_collections(store: &mut HashMap<String, PostWomanCollection>, mut path:
|
||||||
.await;
|
.await;
|
||||||
(res, _name, before, suffix)
|
(res, _name, before, suffix)
|
||||||
};
|
};
|
||||||
if parallel {
|
if *parallel {
|
||||||
joinset.spawn(task);
|
joinset.spawn(task);
|
||||||
} else {
|
} else {
|
||||||
let (res, name, before, num) = task.await;
|
let (res, name, before, num) = task.await;
|
||||||
print_results(res?, name, before, num);
|
match res {
|
||||||
|
Ok(success) => print_results(true, success, name, before, num),
|
||||||
|
Err(e) => print_results(false, e.to_string(), name, before, num),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
while let Some(j) = joinset.join_next().await {
|
while let Some(j) = joinset.join_next().await {
|
||||||
match j {
|
match j {
|
||||||
Ok((res, name, before, num)) => print_results(res?, name, before, num),
|
|
||||||
Err(e) => eprintln!("! error joining task: {e}"),
|
Err(e) => eprintln!("! error joining task: {e}"),
|
||||||
|
Ok((res, name, before, num)) => match res {
|
||||||
|
Err(e) => print_results(false, e.to_string(), name, before, num),
|
||||||
|
Ok(success) => print_results(true, success, name, before, num),
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn print_results(res: String, name: String, before: chrono::DateTime<chrono::Local>, suffix: String) {
|
fn print_results(success: bool, res: String, name: String, before: chrono::DateTime<chrono::Local>, suffix: String) {
|
||||||
let after = chrono::Local::now();
|
let after = chrono::Local::now();
|
||||||
let elapsed = (after - before).num_milliseconds();
|
let elapsed = (after - before).num_milliseconds();
|
||||||
let timestamp = after.format(TIMESTAMP_FMT);
|
let timestamp = after.format(TIMESTAMP_FMT);
|
||||||
eprintln!(" + [{timestamp}] {name} {suffix}done in {elapsed}ms", );
|
let symbol = if success { " + " } else { "!! " };
|
||||||
|
let verb = if success { "done in" } else { "failed after" };
|
||||||
|
eprintln!("{symbol}[{timestamp}] {name} {suffix}{verb} {elapsed}ms", );
|
||||||
print!("{}", res);
|
print!("{}", res);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue