use crate::api::schema::*; use failure::*; use serde_json::{json, Value}; #[derive(Debug)] enum RawArgument { Separator, Argument { value: String }, Option { name: String, value: Option }, } fn parse_argument(arg: &str) -> RawArgument { let chars: Vec = arg.chars().collect(); let length = chars.len(); if length >= 2 && chars[0] == '-' && chars[1] == '-' { if length == 2 { return RawArgument::Separator; } for start in 2..length { if chars[start] == '=' { let name: String = chars[2..start].iter().collect(); let value: String = chars[start+1..length].iter().collect(); return RawArgument::Option { name, value: Some(value) } } } let name: String = chars[2..].iter().collect(); return RawArgument::Option { name: name, value: None } } RawArgument::Argument { value: arg.to_string() } } pub fn parse_arguments(args: &Vec, schema: &Schema) -> Value { println!("ARGS {:?}", args); let properties = match schema { Schema::Object(ObjectSchema { properties, .. }) => properties, _ => panic!("Expected Object Schema."), }; let mut data: Vec<(String, String)> = vec![]; let mut rest: Vec = 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 { if let Some(Schema::Boolean(boolean_schema)) = properties.get::(&name) { if let Some(default) = boolean_schema.default { if default == false { data.push((name, "true".to_string())); } else { panic!("negative Bool requires argument"); } } 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; } } println!("Options {:?}", data); println!("REST {:?}", rest); match parse_parameter_strings(&data, schema, true) { Ok(value) => value, Err(perror) => { panic!(format!("{:?}", perror)); } } }