I've got this Clap CLI definition:
#[derive(Parser, Debug)]
#[command(author, version, about, long_about = None)]
struct Cli {
#[arg(short, long, default_value_t = String::from("stdout"))]
/// host:port, or alternatively "stdout" which will deactivate the udp sender and just print to stdout.
udp_target: String,
#[arg(short = 'n', long)]
hostname: String,
#[arg(short = 'z', long)]
skip_zone: Vec<u8>,
#[arg(short = 's', long)]
skip_sysinfo_zone: Vec<String>,
#[arg(short, long)]
debug: bool,
#[arg(short = 'S', long)]
/// specify this to omit the zone tag. If you have more then one zone, the data will be mixed / scrambled into a single metric!
single: bool,
#[arg(short, long)]
/// format: zone;devisor?;regex_unpacker?;cmd;arg1?;..;argN? - ?=optional, use ";;" to skip in-between parts.
external: Vec<External>,
#[arg(short = 'D', long, default_value_t = 1000.0)]
zone_devisor: f32,
#[arg(short, long, default_value_t = 80)]
/// how often should variables be sent when their value doesn't change? in seconds.
minimum_frequency: u16,
}
#[derive(Debug, Clone)]
struct External {
zone: String,
devisor: f32,
regex_unpack: String,
cmd: String,
args: Vec<String>,
}
// https://doc.rust-lang.org/std/str/trait.FromStr.html
impl FromStr for External {
type Err = std::string::ParseError;
fn from_str(s: &str) -> Result<Self, Self::Err> {
let parts: Vec<&str> = s.split(";").collect();
if parts.len() < 4 {
panic!("An external command definition requires at least 4 parts, see definition in help output.");
}
Ok(External {
zone: String::from(parts[0]),
devisor: parts[1].parse().unwrap_or(1.0),
regex_unpack: String::from(parts[2]),
cmd: String::from(parts[3]),
args: parts[4..].iter().map(|x| String::from(*x)).collect(),
})
}
}
And in the FromStr implementation I'd like to throw an Error (that contains a &str or String) instead of using the panic!(..)
macro.
But nothing I've tried so far worked. Help please..