router: cli: move freestanding new parse loop into its method

Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
This commit is contained in:
Wolfgang Bumiller 2024-07-04 09:54:45 +02:00
parent 95c0614ccd
commit 9288c00372

View File

@ -319,104 +319,87 @@ impl<'t, 'o> ParseOptions<'t, 'o> {
A: IntoIterator<Item = AI>, A: IntoIterator<Item = AI>,
AI: AsRef<str>, AI: AsRef<str>,
{ {
parse_parameters(args, self) let mut errors = ParameterError::new();
} let mut positional = Vec::new();
}
pub(crate) fn parse_parameters<A, AI>( let mut args = args.into_iter().peekable();
args: A, while let Some(orig_arg) = args.next() {
parse_opts: ParseOptions<'_, '_>, let arg = orig_arg.as_ref();
) -> Result<Vec<AI>, ParameterError>
where
A: IntoIterator<Item = AI>,
AI: AsRef<str>,
{
let mut errors = ParameterError::new();
let mut positional = Vec::new();
let mut args = args.into_iter().peekable(); if arg == "--" {
while let Some(orig_arg) = args.next() { if self.retain_separator {
let arg = orig_arg.as_ref(); positional.push(orig_arg);
if arg == "--" {
if parse_opts.retain_separator {
positional.push(orig_arg);
}
break;
}
let option = match arg.strip_prefix("--") {
Some(opt) => opt,
None => {
positional.push(orig_arg);
if parse_opts.stop_at_positional {
break;
} }
break;
}
let option = match arg.strip_prefix("--") {
Some(opt) => opt,
None => {
positional.push(orig_arg);
if self.stop_at_positional {
break;
}
continue;
}
};
if let Some(eq) = option.find('=') {
let (option, argument) = (&option[..eq], &option[(eq + 1)..]);
if self.deny_unknown && !self.option_schemas.contains_key(option) {
if self.stop_at_unknown {
positional.push(orig_arg);
break;
}
errors.push(option.to_string(), format_err!("unknown option {option:?}"));
}
self.target.push((option.to_string(), argument.to_string()));
continue; continue;
} }
};
if let Some(eq) = option.find('=') { if self.deny_unknown && !self.option_schemas.contains_key(option) {
let (option, argument) = (&option[..eq], &option[(eq + 1)..]); if self.stop_at_unknown {
if parse_opts.deny_unknown && !parse_opts.option_schemas.contains_key(option) {
if parse_opts.stop_at_unknown {
positional.push(orig_arg); positional.push(orig_arg);
break; break;
} }
errors.push(option.to_string(), format_err!("unknown option {option:?}")); errors.push(option.to_string(), format_err!("unknown option {option:?}"));
} }
parse_opts
.target
.push((option.to_string(), argument.to_string()));
continue;
}
if parse_opts.deny_unknown && !parse_opts.option_schemas.contains_key(option) { match self.option_schemas.get(option) {
if parse_opts.stop_at_unknown { Some(Schema::Boolean(schema)) => {
positional.push(orig_arg); if let Some(value) = args.next_if(|v| parse_boolean(v.as_ref()).is_ok()) {
break; self.target
} .push((option.to_string(), value.as_ref().to_string()));
errors.push(option.to_string(), format_err!("unknown option {option:?}")); } else {
} // next parameter is not a boolean value
if schema.default == Some(true) {
match parse_opts.option_schemas.get(option) { // default-true booleans cannot be passed without values:
Some(Schema::Boolean(schema)) => { errors.push(option.to_string(), format_err!("missing boolean value."));
if let Some(value) = args.next_if(|v| parse_boolean(v.as_ref()).is_ok()) { }
parse_opts self.target.push((option.to_string(), "true".to_string()))
.target
.push((option.to_string(), value.as_ref().to_string()));
} else {
// next parameter is not a boolean value
if schema.default == Some(true) {
// default-true booleans cannot be passed without values:
errors.push(option.to_string(), format_err!("missing boolean value."));
} }
parse_opts }
.target _ => {
.push((option.to_string(), "true".to_string())) // no schema, assume `--key value`.
let next = match args.next() {
Some(next) => next.as_ref().to_string(),
None => {
errors
.push(option.to_string(), format_err!("missing parameter value."));
break;
}
};
self.target.push((option.to_string(), next.to_string()));
continue;
} }
} }
_ => {
// no schema, assume `--key value`.
let next = match args.next() {
Some(next) => next.as_ref().to_string(),
None => {
errors.push(option.to_string(), format_err!("missing parameter value."));
break;
}
};
parse_opts
.target
.push((option.to_string(), next.to_string()));
continue;
}
} }
}
if !errors.is_empty() { if !errors.is_empty() {
return Err(errors); return Err(errors);
} }
positional.extend(args); positional.extend(args);
Ok(positional) Ok(positional)
}
} }