use getopts::Options;
use std::env;
use std::io::IsTerminal;
use std::path::PathBuf;
use std::process;
#[derive(Debug, Default)]
pub struct Args {
pub config: Option<PathBuf>,
pub server: Option<String>,
pub auth: Option<String>,
pub url: Option<String>,
pub remote: Option<String>,
pub files: Vec<String>,
pub oneshot: bool,
pub expire: Option<String>,
pub prettify: bool,
pub print_server_version: bool,
pub list_files: bool,
pub delete: bool,
pub filename: Option<String>,
}
impl Args {
pub fn parse() -> Self {
let mut opts = Options::new();
opts.optflag("h", "help", "prints help information");
opts.optflag("v", "version", "prints version information");
opts.optflag("V", "server-version", "retrieves the server version");
opts.optflag("l", "list", "lists files on the server");
opts.optflag("d", "delete", "delete files from server");
opts.optflag("o", "oneshot", "generates one shot links");
opts.optflag("p", "pretty", "prettifies the output");
opts.optopt("c", "config", "sets the configuration file", "CONFIG");
opts.optopt(
"s",
"server",
"sets the address of the rustypaste server",
"SERVER",
);
opts.optopt(
"a",
"auth",
"sets the authentication or delete token",
"TOKEN",
);
opts.optopt("u", "url", "sets the URL to shorten", "URL");
opts.optopt("r", "remote", "sets the remote URL for uploading", "URL");
opts.optopt(
"e",
"expire",
"sets the expiration time for the link",
"TIME",
);
opts.optopt("n", "filename", "sets and overrides the filename", "NAME");
let env_args: Vec<String> = env::args().collect();
let matches = match opts.parse(&env_args[1..]) {
Ok(m) => m,
Err(e) => {
eprintln!("Argument error: `{e}`");
process::exit(1);
}
};
if matches.opt_present("h")
|| (matches.free.is_empty()
&& !matches.opt_present("u")
&& !matches.opt_present("r")
&& !matches.opt_present("V")
&& !matches.opt_present("l")
&& !matches.opt_present("d")
&& !matches.opt_present("v")
&& std::io::stdin().is_terminal())
{
let usage = format!(
"\n{} {} \u{2014} {}.\
\n\u{221F} written by {}\
\n\u{221F} licensed under MIT <{}>\
\n\nUsage:\n {} [options] <file(s)>",
env!("CARGO_PKG_NAME"),
env!("CARGO_PKG_VERSION"),
env!("CARGO_PKG_DESCRIPTION"),
env!("CARGO_PKG_AUTHORS"),
env!("CARGO_PKG_REPOSITORY"),
"rpaste",
);
println!("{}", opts.usage(&usage));
process::exit(0)
}
if matches.opt_present("v") {
println!("{} {}", env!("CARGO_PKG_NAME"), env!("CARGO_PKG_VERSION"));
process::exit(0)
}
Args {
config: env::var("RPASTE_CONFIG")
.ok()
.or_else(|| matches.opt_str("c"))
.map(PathBuf::from),
server: matches.opt_str("s"),
auth: matches.opt_str("a"),
url: matches.opt_str("u"),
remote: matches.opt_str("r"),
oneshot: matches.opt_present("o"),
expire: matches.opt_str("e"),
prettify: matches.opt_present("p"),
print_server_version: matches.opt_present("V"),
list_files: matches.opt_present("l"),
delete: matches.opt_present("d"),
filename: matches.opt_str("n"),
files: matches.free,
}
}
}