use std::path::PathBuf;
use clap::{command, value_parser, Arg, ArgAction, Command, ValueHint};
use cli_utils::BoxResult;
use const_format::formatcp;
use crate::config::{Config, Settings};
pub const A_S_VERSION: char = 'V';
pub const A_L_VERSION: &str = "version";
pub const A_S_QUIET: char = 'q';
pub const A_L_QUIET: &str = "quiet";
pub const A_S_VERBOSE: char = 'v';
pub const A_L_VERBOSE: &str = "verbose";
pub const A_S_BASE_IRI: char = 'b';
pub const A_L_BASE_IRI: &str = "base-iri";
pub const A_L_OWL_FILE: &str = "owl-file";
pub const A_L_SHACL_FILE: &str = "shacl-file";
pub const A_L_PREFIXES_FILE: &str = "prefixes-file";
fn arg_version() -> Arg {
Arg::new(A_L_VERSION)
.help(formatcp!(
"Print version information and exit. \
May be combined with -{A_S_QUIET},--{A_L_QUIET}, \
to really only output the version string."
))
.short(A_S_VERSION)
.long(A_L_VERSION)
.action(ArgAction::SetTrue)
}
fn arg_quiet() -> Arg {
Arg::new(A_L_QUIET)
.help("Minimize or suppress output to stderr")
.long_help("Minimize or suppress output to stderr; stdout is never used by this program, with or without this option set.")
.action(ArgAction::SetTrue)
.short(A_S_QUIET)
.long(A_L_QUIET)
.conflicts_with(A_L_VERBOSE)
}
fn arg_verbose() -> Arg {
Arg::new(A_L_VERBOSE)
.help("more verbose output (useful for debugging)")
.short(A_S_VERBOSE)
.long(A_L_VERBOSE)
.action(ArgAction::SetTrue)
}
fn arg_base_iri() -> Arg {
Arg::new(A_L_BASE_IRI)
.help("Sets the OWL ontologies base-IRI")
.short(A_S_BASE_IRI)
.long(A_L_BASE_IRI)
.action(ArgAction::Set)
}
fn arg_owl_file() -> Arg {
Arg::new(A_L_OWL_FILE)
.help("The OWL input file")
.action(ArgAction::Set)
.value_parser(value_parser!(std::path::PathBuf))
.value_hint(ValueHint::FilePath)
.value_name("OWL_FILE")
.required(true)
}
fn arg_shacl_file() -> Arg {
Arg::new(A_L_SHACL_FILE)
.help("The SHACL output file")
.action(ArgAction::Set)
.value_parser(value_parser!(std::path::PathBuf))
.value_hint(ValueHint::FilePath)
.value_name("SHACL_FILE")
}
fn arg_prefixes_file() -> Arg {
Arg::new(A_L_PREFIXES_FILE)
.help("The prefixes output file")
.action(ArgAction::Set)
.value_parser(value_parser!(std::path::PathBuf))
.value_hint(ValueHint::FilePath)
.value_name("PREFIXES_FILE")
}
pub fn args_matcher() -> Command {
command!()
.about(clap::crate_description!())
.bin_name(clap::crate_name!())
.help_expected(true)
.disable_version_flag(true)
.arg(arg_version())
.arg(arg_quiet())
.arg(arg_verbose())
.arg(arg_base_iri())
.arg(arg_owl_file())
.arg(arg_shacl_file())
.arg(arg_prefixes_file())
}
#[allow(clippy::print_stdout)]
fn print_version_and_exit(quiet: bool) {
if !quiet {
print!("{} ", clap::crate_name!());
}
println!("{}", crate::VERSION);
std::process::exit(0);
}
#[derive(Clone, Debug)]
pub struct Args {
pub quiet: bool,
pub verbose: bool,
pub config: Config,
}
pub fn parse() -> BoxResult<Args> {
let args = args_matcher().get_matches();
let quiet = args.get_flag(A_L_QUIET);
let version = args.get_flag(A_L_VERSION);
if version {
print_version_and_exit(quiet);
}
let verbose = args.get_flag(A_L_VERBOSE);
let base_iri = args.get_one::<String>(A_L_BASE_IRI).cloned();
let owl = args
.get_one::<PathBuf>(A_L_OWL_FILE)
.cloned()
.expect("OWL input file is required");
let shacl = args.get_one::<PathBuf>(A_L_SHACL_FILE).cloned();
let prefixes = args.get_one::<PathBuf>(A_L_PREFIXES_FILE).cloned();
let settings = Settings::default();
let parsed_args = Args {
quiet,
verbose,
config: Config {
settings,
base_iri,
owl,
shacl,
prefixes,
},
};
Ok(parsed_args)
}