pub use clap::Parser;
use lazy_static::lazy_static;
use qrcodegen::QrCodeEcc;
use regex::Regex;
pub fn parse_hex_color(hex: &str) -> Result<String, String> {
lazy_static! {
static ref HEX_RE: Regex = Regex::new("^([0-9A-Fa-f]{3}){1,2}$").unwrap();
}
match HEX_RE.is_match(hex) {
true => Ok(hex.to_string()),
false => Err(format!("{hex} is not a valid hex color code")),
}
}
pub fn parse_level(ecl: &str) -> Result<QrCodeEcc, String> {
Ok(match ecl {
"L" | "low" => QrCodeEcc::Low,
"M" | "medium" => QrCodeEcc::Medium,
"Q" | "quartile" => QrCodeEcc::Quartile,
"H" | "high" => QrCodeEcc::High,
_ => return Err("invalid error correction level".to_string()),
})
}
const DEF_EDGE: u8 = 4;
#[derive(Parser, Debug)]
#[clap(version, about)]
#[clap(help_template(
"\
{name} {version} - {about}
{usage-heading} {usage}
{all-args}
"
))]
pub struct Args {
#[clap(short = 'o', long = "output", default_missing_value = "qr.png", value_parser)]
pub qr_path: Option<String>,
#[clap(short = 'F', long, requires = "qr_path")]
pub force: bool,
#[clap(short, long)]
pub terminal: bool,
#[clap(
short = 'l',
long = "level",
default_value = "M",
value_parser = parse_level
)]
pub level: QrCodeEcc,
#[clap(short = 'p', long = "path", required = false)]
pub logo_path: Option<std::path::PathBuf>,
#[clap(short = 'P', long = "proportion", default_value_t = 0.25, value_parser)]
pub proportion: f64,
#[clap(short = 'e', long = "edge", default_value_t = DEF_EDGE, value_parser)]
pub edge: u8,
#[clap(
short,
long,
conflicts_with = "terminal",
default_value = "000",
value_parser = parse_hex_color
)]
pub fg: String,
#[clap(
short,
long,
conflicts_with = "terminal",
default_value = "fff",
value_parser = parse_hex_color
)]
pub bg: String,
#[clap(short, long, conflicts_with = "terminal", default_value_t = 8, value_parser)]
pub scale: u8,
#[clap(value_parser)]
pub string: Option<String>,
}