getopt parser fixes and cleanups
This commit is contained in:
		@ -171,6 +171,14 @@ macro_rules! parameter {
 | 
			
		||||
    }};
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
pub fn parse_boolean(value_str: &str) -> Result<bool, Error> {
 | 
			
		||||
    match value_str.to_lowercase().as_str() {
 | 
			
		||||
        "1" | "on" | "yes" | "true" => Ok(true),
 | 
			
		||||
        "0" | "off" | "no" | "false" => Ok(false),
 | 
			
		||||
        _ => bail!("Unable to parse boolean option."),
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
fn parse_simple_value(value_str: &str, schema: &Schema) -> Result<Value, Error> {
 | 
			
		||||
 | 
			
		||||
    let value = match schema {
 | 
			
		||||
@ -178,11 +186,7 @@ fn parse_simple_value(value_str: &str, schema: &Schema) -> Result<Value, Error>
 | 
			
		||||
            bail!("internal error - found Null schema.");
 | 
			
		||||
        }
 | 
			
		||||
        Schema::Boolean(_boolean_schema) => {
 | 
			
		||||
            let res = match value_str.to_lowercase().as_str() {
 | 
			
		||||
                "1" | "on" | "yes" | "true" => true,
 | 
			
		||||
                "0" | "off" | "no" | "false" => false,
 | 
			
		||||
                _ => bail!("Unable to parse boolean option."),
 | 
			
		||||
            };
 | 
			
		||||
            let res = parse_boolean(value_str)?;
 | 
			
		||||
            Value::Bool(res)
 | 
			
		||||
        }
 | 
			
		||||
        Schema::Integer(integer_schema) => {
 | 
			
		||||
 | 
			
		||||
@ -1,6 +1,7 @@
 | 
			
		||||
use crate::api::schema::*;
 | 
			
		||||
 | 
			
		||||
use failure::*;
 | 
			
		||||
use std::collections::HashMap;
 | 
			
		||||
use serde_json::{json, Value};
 | 
			
		||||
 | 
			
		||||
#[derive(Debug)]
 | 
			
		||||
@ -72,23 +73,43 @@ pub fn parse_arguments(
 | 
			
		||||
                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::<str>(&name) {
 | 
			
		||||
                            let param_schema = properties.get::<str>(&name);
 | 
			
		||||
                            let (want_bool, can_default) = match param_schema {
 | 
			
		||||
                                Some(Schema::Boolean(boolean_schema)) => {
 | 
			
		||||
                                    if let Some(default) = boolean_schema.default {
 | 
			
		||||
                                            if default == false {
 | 
			
		||||
                                        if default == true { (true, false); }
 | 
			
		||||
                                    }
 | 
			
		||||
                                    (true, true)
 | 
			
		||||
                                }
 | 
			
		||||
                                _ => (false, false),
 | 
			
		||||
                            };
 | 
			
		||||
 | 
			
		||||
                            if want_bool {
 | 
			
		||||
 | 
			
		||||
                                let mut next_is_bool = false;
 | 
			
		||||
                                if (pos + 1) < args.len() {
 | 
			
		||||
                                    let next = &args[pos+1];
 | 
			
		||||
                                    if let Ok(_) = parse_boolean(next) { next_is_bool = true; }
 | 
			
		||||
                                }
 | 
			
		||||
 | 
			
		||||
                                if next_is_bool {
 | 
			
		||||
                                    pos += 1;
 | 
			
		||||
                                    data.push((name, args[pos].clone()));
 | 
			
		||||
                                } else if can_default {
 | 
			
		||||
                                   data.push((name, "true".to_string()));
 | 
			
		||||
                                } else {
 | 
			
		||||
                                    errors.push(format_err!("parameter '{}': {}", name,
 | 
			
		||||
                                                                        "boolean requires argument."));
 | 
			
		||||
                                                            "missing boolean value."));
 | 
			
		||||
                                }
 | 
			
		||||
 | 
			
		||||
                            } else {
 | 
			
		||||
                                            data.push((name, "true".to_string()));
 | 
			
		||||
                                        }
 | 
			
		||||
                                    }
 | 
			
		||||
 | 
			
		||||
                                if (pos + 1) < args.len() {
 | 
			
		||||
                                    pos += 1;
 | 
			
		||||
                                    data.push((name, args[pos].clone()));
 | 
			
		||||
                                } else {
 | 
			
		||||
                                    errors.push(format_err!("parameter '{}': {}", name,
 | 
			
		||||
                                                            "missing parameter value."));
 | 
			
		||||
                                }
 | 
			
		||||
                            }
 | 
			
		||||
                        }
 | 
			
		||||
@ -113,3 +134,30 @@ pub fn parse_arguments(
 | 
			
		||||
 | 
			
		||||
    Ok((options,rest))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#[test]
 | 
			
		||||
fn test_boolean_arg() {
 | 
			
		||||
 | 
			
		||||
    let schema = parameter!{enable => Boolean!{ optional => false }};
 | 
			
		||||
 | 
			
		||||
    let mut variants: Vec<Vec<&str>> = vec![];
 | 
			
		||||
    variants.push(vec!["-enable"]);
 | 
			
		||||
    variants.push(vec!["-enable=1"]);
 | 
			
		||||
    variants.push(vec!["-enable", "yes"]);
 | 
			
		||||
    variants.push(vec!["--enable", "1"]);
 | 
			
		||||
 | 
			
		||||
    for args in variants {
 | 
			
		||||
        let string_args = args.iter().map(|s| s.to_string()).collect();
 | 
			
		||||
        let res = parse_arguments(&string_args, &schema);
 | 
			
		||||
        println!("RES: {:?}", res);
 | 
			
		||||
        assert!(res.is_ok());
 | 
			
		||||
        if let Ok((options, rest)) = res {
 | 
			
		||||
            assert!(options["enable"] == true);
 | 
			
		||||
            assert!(rest.len() == 0);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    //Ok((options, rest)) => {
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
		Reference in New Issue
	
	Block a user