mod api;
mod auth;
mod cli;
mod config;
mod error;
mod output;
mod store;
use clap::{CommandFactory, Parser};
use cli::exit_codes::{
EXIT_AUTH_REQUIRED, EXIT_GENERAL_ERROR, EXIT_NETWORK_ERROR, EXIT_NOT_FOUND, EXIT_RATE_LIMITED,
EXIT_SUCCESS,
};
use cli::{Cli, Commands};
use error::XurlError;
use output::OutputConfig;
fn main() {
#[cfg(unix)]
unsafe {
libc::signal(libc::SIGPIPE, libc::SIG_DFL);
}
let cli = Cli::parse();
if let Some(ref cmd) = cli.command {
match cmd {
Commands::Completions { shell } => {
let mut cmd = Cli::command();
clap_complete::generate(*shell, &mut cmd, "xr", &mut std::io::stdout());
return;
}
Commands::Version => {
println!("xr {}", env!("CARGO_PKG_VERSION"));
return;
}
Commands::Schema { command, list, all } => {
let out = OutputConfig::new(cli.output.clone(), cli.quiet);
match cli::commands::schema::run_schema(command.as_deref(), *list, *all) {
Ok(()) => return,
Err(e) => {
out.print_error(&e, EXIT_GENERAL_ERROR);
std::process::exit(EXIT_GENERAL_ERROR);
}
}
}
_ => {}
}
}
let out = OutputConfig::new(cli.output.clone(), cli.quiet);
match cli::commands::run(cli, &out) {
Ok(()) => std::process::exit(EXIT_SUCCESS),
Err(e) => {
let code = exit_code_for_error(&e);
out.print_error(&e, code);
std::process::exit(code);
}
}
}
fn exit_code_for_error(e: &XurlError) -> i32 {
match e {
XurlError::Auth(_) | XurlError::TokenStore(_) => EXIT_AUTH_REQUIRED,
XurlError::Http(msg) | XurlError::Api(msg)
if msg.contains("401") || msg.contains("Unauthorized") =>
{
EXIT_AUTH_REQUIRED
}
XurlError::Http(msg) | XurlError::Api(msg) if msg.contains("429") => EXIT_RATE_LIMITED,
XurlError::Http(msg) | XurlError::Api(msg) if msg.contains("404") => EXIT_NOT_FOUND,
XurlError::Io(_) => EXIT_NETWORK_ERROR,
_ => EXIT_GENERAL_ERROR,
}
}