use crate::map::MapPropertySource;
use crate::*;
#[cfg(feature = "enable_clap")]
use clap::{App, Arg};
#[cfg(feature = "enable_clap")]
use regex::Regex;
use std::collections::HashMap;
#[cfg(feature = "enable_clap")]
const NOT_POSSIBLE: &'static str = "Not possible";
pub enum SysArgsMode {
#[cfg(feature = "enable_clap")]
Auto(SysArgsParam),
Custom(Vec<(String, Property)>),
}
#[cfg(feature = "enable_clap")]
pub struct SysArgsParam {
pub name: &'static str,
pub version: &'static str,
pub author: Option<&'static str>,
pub about: Option<&'static str>,
}
#[macro_export]
#[cfg(feature = "enable_clap")]
macro_rules! auto_read_sys_args_param {
() => {
args::SysArgsParam {
name: env!("CARGO_PKG_NAME"),
version: env!("CARGO_PKG_VERSION"),
author: option_env!("CARGO_PKG_AUTHORS"),
about: option_env!("CARGO_PKG_DESCRIPTION"),
}
};
}
pub(crate) struct SysArgs(pub(crate) MapPropertySource);
impl SysArgs {
pub fn new(args: SysArgsMode) -> Self {
let args = match args {
#[cfg(feature = "enable_clap")]
SysArgsMode::Auto(arg) => Self::new_default_args(arg),
SysArgsMode::Custom(arg) => arg,
};
let mut map = HashMap::new();
for (k, v) in args {
map.insert(k, v);
}
SysArgs(MapPropertySource::new("SystemArguments".to_owned(), map))
}
#[cfg(feature = "enable_clap")]
fn new_default_args(param: SysArgsParam) -> Vec<(String, Property)> {
let mut app = App::new(param.name).version(param.version);
if let Some(a) = param.author {
app = app.author(a);
}
if let Some(a) = param.about {
app = app.about(a);
}
let matches = app
.arg(
Arg::with_name("property")
.short("P")
.long("property")
.value_name("KEY=VALUE")
.multiple(true)
.number_of_values(1)
.takes_value(true)
.help("Set properties"),
)
.get_matches();
lazy_static::lazy_static! {
static ref RE: Regex = Regex::new(
r"^([^=]+)=(.+)$"
)
.expect(NOT_POSSIBLE);
}
matches
.values_of_lossy("property")
.unwrap_or(vec![])
.iter()
.flat_map(|k| match RE.captures(&k) {
Some(ref v) => Some((
v.get(1).unwrap().as_str().to_owned(),
Property::Str(v.get(2).unwrap().as_str().to_owned()),
)),
_ => None,
})
.collect()
}
}
#[cfg(feature = "enable_clap")]
impl Default for SysArgs {
fn default() -> Self {
SysArgs::new(SysArgsMode::Auto(auto_read_sys_args_param!()))
}
}
#[cfg(test)]
mod tests {
#[test]
#[cfg(feature = "enable_clap")]
fn test_auto_read_sys_args_param() {
use crate::args;
let m = auto_read_sys_args_param!();
assert_eq!("salak", m.name);
}
}