proxmox-backup/src/getopts.rs

116 lines
3.7 KiB
Rust
Raw Normal View History

2018-11-16 12:14:11 +00:00
use crate::api::schema::*;
use failure::*;
use serde_json::{json, Value};
#[derive(Debug)]
enum RawArgument {
Separator,
Argument { value: String },
Option { name: String, value: Option<String> },
}
fn parse_argument(arg: &str) -> RawArgument {
let chars: Vec<char> = arg.chars().collect();
let length = chars.len();
if length >= 2 {
2018-11-16 12:14:11 +00:00
if length == 2 { return RawArgument::Separator; }
if chars[0] == '-' {
let first = if chars[1] == '-' { 2 } else { 1 };
2018-11-16 12:14:11 +00:00
for start in first..length {
if chars[start] == '=' {
let name: String = chars[first..start].iter().collect();
let value: String = chars[start+1..length].iter().collect();
return RawArgument::Option { name, value: Some(value) }
}
}
2018-11-16 12:14:11 +00:00
let name: String = chars[first..].iter().collect();
return RawArgument::Option { name: name, value: None }
}
2018-11-16 12:14:11 +00:00
}
RawArgument::Argument { value: arg.to_string() }
}
2018-11-17 08:57:26 +00:00
pub fn parse_arguments(
args: &Vec<String>,
schema: &Schema,
) -> Result<(Value,Vec<String>), ParameterError> {
2018-11-16 12:14:11 +00:00
2018-11-17 08:57:26 +00:00
let mut errors = ParameterError::new();
2018-11-16 12:14:11 +00:00
let properties = match schema {
Schema::Object(ObjectSchema { properties, .. }) => properties,
2018-11-17 08:57:26 +00:00
_ => {
errors.push(format_err!("parse arguments failed - got strange parameters (expected object schema)."));
return Err(errors);
},
2018-11-16 12:14:11 +00:00
};
let mut data: Vec<(String, String)> = vec![];
let mut rest: Vec<String> = vec![];
let mut pos = 0;
let mut skip = false;
loop {
if skip {
rest.push(args[pos].clone());
} else {
match parse_argument(&args[pos]) {
RawArgument::Separator => {
skip = true;
}
RawArgument::Option { name, value } => {
match value {
None => {
if pos < args.len() {
if let RawArgument::Argument { value: next } = parse_argument(&args[pos+1]) {
pos += 1;
data.push((name, next));
} else {
2018-11-16 15:47:23 +00:00
if let Some(Schema::Boolean(boolean_schema)) = properties.get::<str>(&name) {
if let Some(default) = boolean_schema.default {
2018-11-16 12:14:11 +00:00
if default == false {
data.push((name, "true".to_string()));
} else {
2018-11-17 08:57:26 +00:00
errors.push(format_err!("parameter '{}': {}", name,
"boolean requires argument."));
2018-11-16 12:14:11 +00:00
}
} else {
data.push((name, "true".to_string()));
}
}
}
}
}
Some(v) => {
data.push((name, v));
}
}
}
RawArgument::Argument { value } => {
rest.push(value);
}
}
}
pos += 1;
if pos >= args.len() { break; }
}
2018-11-17 08:57:26 +00:00
if errors.len() > 0 { return Err(errors); }
2018-11-16 12:14:11 +00:00
2018-11-17 08:57:26 +00:00
let options = parse_parameter_strings(&data, schema, true)?;
Ok((options,rest))
2018-11-16 12:14:11 +00:00
}