#[cfg(feature = "clap")]
use clap::Parser;
use clap::{builder::TypedValueParser, ErrorKind};
use std::path::PathBuf;
#[derive(Parser, Debug)]
#[clap(author, about, version)]
pub struct Args {
#[clap(short = 'G')]
pub debug: bool,
#[clap(subcommand)]
pub command: Command,
}
#[derive(Parser, Debug)]
pub enum Command {
#[clap(name = "list", alias = "ls")]
List(List),
#[clap(name = "set")]
Set(Set),
}
#[derive(Parser, Debug)]
pub struct List {
#[clap(short = 'x', parse(from_occurrences))]
pub hex: usize,
#[clap(short = 'F', value_name = "file")]
pub file: Option<PathBuf>,
#[clap(short = 'v', parse(from_occurrences))]
pub verbose: usize,
#[clap(short = 'k')]
pub kernel: bool,
#[clap(short = 'D')]
pub always_domain_number: bool,
#[clap(short = 'n', parse(from_occurrences))]
pub as_numbers: usize,
#[clap(short = 'A', value_enum, value_name = "method")]
pub method: Option<PreferredMethod>,
#[clap(short = 'O', value_name = "param>=<value", value_parser = ParameterValueParser)]
pub(crate) parameter_value: Option<ParameterValue>,
#[clap(short = 'i', value_name = "file")]
pub(crate) pci_ids_path: Option<PathBuf>,
#[clap(short = 's', value_name = "[[[[<domain>]:]<bus>]:][<device>][.[<func>]]")]
pub(crate) address: Option<PathBuf>,
}
#[derive(Debug, Clone)]
#[cfg_attr(feature = "clap", derive(clap::ValueEnum))]
pub enum PreferredMethod {
LinuxSysfs,
#[clap(name = "linux-proc")]
LinuxProcfs,
IntelConf1,
IntelConf2,
#[cfg(target_os = "freebsd")]
FbsdDevice,
#[cfg(target_os = "netbsd")]
NbsdDevice,
#[cfg(target_os = "openbsd")]
ObsdDevice,
#[cfg(target_os = "macos")]
Darwin,
Dump,
}
#[derive(Debug, Clone)]
pub(crate) enum ParameterValue {
DumpName(PathBuf),
ProcPath(PathBuf),
SysfsPath(PathBuf),
NetCacheName(PathBuf),
NetDomain(String),
}
#[derive(Debug, Clone)]
pub(crate) struct ParameterValueParser;
impl TypedValueParser for ParameterValueParser {
type Value = ParameterValue;
fn parse_ref(
&self,
cmd: &clap::Command,
_arg: Option<&clap::Arg>,
value: &std::ffi::OsStr,
) -> Result<Self::Value, clap::Error> {
let mut cmd = cmd.clone();
let (param, value) = value
.to_str()
.and_then(|s| s.split_once('='))
.ok_or_else(|| cmd.error(ErrorKind::InvalidValue, "format is <key> = <value>"))?;
match param {
"dump.name" => Ok(ParameterValue::DumpName(PathBuf::from(value))),
"proc.path" => Ok(ParameterValue::ProcPath(PathBuf::from(value))),
"sysfs.path" => Ok(ParameterValue::SysfsPath(PathBuf::from(value))),
"net.cache_name" => Ok(ParameterValue::NetCacheName(PathBuf::from(value))),
"net.domain" => Ok(ParameterValue::NetDomain(value.into())),
_ => Err(cmd.error(
ErrorKind::InvalidValue,
"available values: dump.name, proc.path, sysfs.path, net.cache_name, net.domain",
)),
}
}
}
#[derive(Parser, Debug)]
pub struct Set;