A much cleaner way of doing things, uses clap::Arg::get_value_parser()
instead of accessing private fields that had been patched to make public. For the argument handling to become more sophisticated it will need to be refactored into its own Xilem View
.
G54GZBS464DFT2224SUTRWPRRSLUQKWDXY2YA7USW7UZ7VPXIHEAC
OVEFU3K2T36H3EMYOIF6U7AYWMJIV5IJYRL56F3PWRCG7EGEZMQAC
C73UJ7ZYG4EE3YTK3N66GXPNWJHEBSRE4PDQBWMN6SKQ3U6ZYKXAC
JFJVY57RWKT6YJ62MWWOHXSLASLWPORFUGF67TVTW4FW7XBZEAUQC
BMG4FSHNV54VXDHNUVGZOMXQJWLFSUF3M5NCN7GJETNIF3QTHELQC
REI53XR4WDH5EKLTXTFVTOVWCCFRWTFH4GQS6DSNM5LSRFTX7HJQC
ZYNEMGAZXWHIWGNPB2RTYG3JWTH5Y5XY4JWJ3TTPANIOORTCLISAC
A4E5KLI2CEHJLO6WUME2VIXPK4C2DXHCBVEK2TJTLHGCRCZ2ZC7QC
4MMVEN5YUVUQ5RO3X2XKZVBMBMHOEJIYUCLKL63EPRUVQQRQXUAAC
BSJYWOYSJRERQ45AD7RN3364RYQ5P3IM76S67262VLFZPFO3B5JQC
CQEA2ZDITRMPXKCO5T346QH7JJOOGOPRC66F3MG6VEMEQGLYYUZAC
HEIF2O2ELHA3M7K77CK7AHBZ4656AUS3QW5M4E2DUY7ECOLVWKIAC
struct ArgState {
name: String,
source: ValueSource,
raw_values: Vec<String>,
// Keep the value as a string, but store its corresponding type info
type_id: AnyValueId,
impl Default for AppState {
fn default() -> Self {
Self {
command: String::new(),
arg_matches: Err(clap::Error::new(clap::error::ErrorKind::TooFewValues)),
}
}
self.args = if let Ok(matches) = matches {
matches.args.iter().map(matched_to_state).collect()
} else {
Vec::new()
};
self.arg_matches = cli_command.try_get_matches_from(args_iter);
tracing::debug!("Matches: {:#?}", self.arg_matches);
ArgState {
name: key.to_string(),
source: value.source().unwrap_or(ValueSource::DefaultValue),
raw_values: value
.raw_vals()
.flatten()
.map(|raw_value| raw_value.to_string_lossy().to_string())
.collect(),
type_id: value
.type_id()
.unwrap_or(AnyValueId::of::<dyn std::any::Any>()),
}
}
fn arg_item(matches: &ArgMatches, arg: &clap::Arg) -> impl View<AppState> + ViewMarker {
tracing::debug!("`{:?}`", matches.contains_id("name"));
let source = if let Some(source) = matches.value_source(arg.get_id().as_str()) {
match source {
ValueSource::DefaultValue => "default",
ValueSource::EnvVariable => "environment",
ValueSource::CommandLine => "cmdline",
_ => "todo",
}
} else {
"none"
};
fn arg_item(arg: &ArgState) -> impl View<AppState> + ViewMarker {
let source = match arg.source {
ValueSource::DefaultValue => "default",
ValueSource::EnvVariable => "environment",
ValueSource::CommandLine => "cmdline",
_ => "todo",
let type_id = arg.get_value_parser().type_id();
let type_name = if type_id == value_parser!(String).type_id() {
"string".to_string()
} else {
format!("{:?}", type_id)
el::div((
el::div(state.args.iter().map(arg_item).collect::<Vec<_>>()).attr("id", "sidebar"),
el::div(docs::test()).attr("id", "content"),
))
el::div((el::div(
MockApp::command()
.get_opts()
.filter(|arg| arg_matches.try_contains_id(arg.get_id().as_str()).is_ok())
.map(|arg| arg_item(&arg_matches, arg))
.collect::<Vec<_>>(),
)
.attr("id", "sidebar"),))