mod app;
mod env;
fn usage() {
let pkg_name = env!("CARGO_PKG_NAME");
eprintln!("Usage: {} [OPTIONS] [COMMAND]", pkg_name);
eprintln!();
eprintln!("Options:");
eprintln!(" --dump Dump variables.");
eprintln!(" -h, --help usage");
eprintln!(" --use-stdin Use command stdin as .env");
eprintln!(" --file STRING .env");
}
#[derive(Debug)]
struct Configuration {
command: Vec<String>,
dump: bool,
file: Option<String>,
help: bool,
use_stdin: bool,
}
impl Configuration {
pub fn new(args: &Vec<String>) -> Result<Self, Box<dyn std::error::Error>> {
let mut conf = Self {
command: vec![],
dump: false,
file: None,
help: false,
use_stdin: false,
};
let mut current_section = "";
for arg in args {
if 0 < conf.command.len() {
conf.command.push(arg.to_string());
} else if arg == "--" {
current_section = "";
conf.command.push(arg.to_string());
} else if arg == "--dump" {
conf.dump = true;
current_section = "";
} else if arg == "--file" {
conf.file = Some("".to_string());
current_section = "--file";
} else if arg == "--help" {
conf.help = true;
current_section = "";
} else if arg == "-h" {
conf.help = true;
current_section = "";
} else if arg == "--use-stdin" {
conf.use_stdin = true;
current_section = ""
} else if arg.starts_with("-") {
let err = format!("Unknown option {}.", arg);
return Err(err.into());
} else if current_section == "--file" {
conf.file = Some(arg.to_string());
current_section = "";
} else {
conf.command.push(arg.to_string());
}
}
if conf.file.is_some() {
let file = conf.file.as_ref().unwrap();
if file == "" {
let error = "--file option requires a file path.";
return Err(error.into());
}
}
return Ok(conf);
}
}
fn main() {
let args: Vec<String> = std::env::args().skip(1).collect();
let result = Configuration::new(&args);
if result.is_err() {
let pkg_name = env!("CARGO_PKG_NAME");
eprintln!("{}: {}", pkg_name, result.err().unwrap());
eprintln!();
usage();
std::process::exit(1);
}
let input = result.unwrap();
if input.help {
usage();
} else if input.dump {
let app = app::Application;
let result = app.dump_variables(input.use_stdin, input.file);
if result.is_err() {
let pkg_name = env!("CARGO_PKG_NAME");
eprintln!("{}: {}", pkg_name, result.err().unwrap());
eprintln!();
usage();
std::process::exit(1);
}
} else {
let app = app::Application;
let result = app.execute(input.use_stdin, input.file, &input.command);
if result.is_err() {
eprintln!("ERROR: {}", result.err().unwrap());
std::process::exit(1);
}
let exit_code = result.unwrap();
if exit_code != 0 {
std::process::exit(exit_code);
}
};
}