1 use crate::api
::schema
::*;
4 use std
::collections
::HashMap
;
5 use serde_json
::{json, Value}
;
10 Argument { value: String }
,
11 Option { name: String, value: Option<String> }
,
14 fn parse_argument(arg
: &str) -> RawArgument
{
16 let chars
: Vec
<char> = arg
.chars().collect();
18 let length
= chars
.len();
22 if length
== 2 { return RawArgument::Separator; }
25 let first
= if chars
[1] == '
-' { 2 }
else { 1 }
;
27 for start
in first
..length
{
28 if chars
[start
] == '
='
{
29 let name
: String
= chars
[first
..start
].iter().collect();
30 let value
: String
= chars
[start
+1..length
].iter().collect();
31 return RawArgument
::Option { name, value: Some(value) }
35 let name
: String
= chars
[first
..].iter().collect();
36 return RawArgument
::Option { name: name, value: None }
40 RawArgument
::Argument { value: arg.to_string() }
43 pub fn parse_arguments(
46 ) -> Result
<(Value
,Vec
<String
>), ParameterError
> {
48 let mut errors
= ParameterError
::new();
50 let properties
= match schema
{
51 Schema
::Object(ObjectSchema { properties, .. }
) => properties
,
53 errors
.push(format_err
!("parse arguments failed - got strange parameters (expected object schema)."));
58 let mut data
: Vec
<(String
, String
)> = vec
![];
59 let mut rest
: Vec
<String
> = vec
![];
67 rest
.push(args
[pos
].clone());
69 match parse_argument(&args
[pos
]) {
70 RawArgument
::Separator
=> {
73 RawArgument
::Option { name, value }
=> {
76 let param_schema
= properties
.get
::<str>(&name
);
77 let (want_bool
, can_default
) = match param_schema
{
78 Some(Schema
::Boolean(boolean_schema
)) => {
79 if let Some(default) = boolean_schema
.default {
80 if default == true { (true, false); }
89 let mut next_is_bool
= false;
90 if (pos
+ 1) < args
.len() {
91 let next
= &args
[pos
+1];
92 if let Ok(_
) = parse_boolean(next
) { next_is_bool = true; }
97 data
.push((name
, args
[pos
].clone()));
98 } else if can_default
{
99 data
.push((name
, "true".to_string()));
101 errors
.push(format_err
!("parameter '{}': {}", name
,
102 "missing boolean value."));
107 if (pos
+ 1) < args
.len() {
109 data
.push((name
, args
[pos
].clone()));
111 errors
.push(format_err
!("parameter '{}': {}", name
,
112 "missing parameter value."));
117 data
.push((name
, v
));
121 RawArgument
::Argument { value }
=> {
128 if pos
>= args
.len() { break; }
131 if errors
.len() > 0 { return Err(errors); }
133 let options
= parse_parameter_strings(&data
, schema
, true)?
;
140 fn test_boolean_arg() {
142 let schema
= parameter
!{enable => Boolean!{ optional => false }
};
144 let mut variants
: Vec
<Vec
<&str>> = vec
![];
145 variants
.push(vec
!["-enable"]);
146 variants
.push(vec
!["-enable=1"]);
147 variants
.push(vec
!["-enable", "yes"]);
148 variants
.push(vec
!["--enable", "1"]);
150 for args
in variants
{
151 let string_args
= args
.iter().map(|s
| s
.to_string()).collect();
152 let res
= parse_arguments(&string_args
, &schema
);
153 println
!("RES: {:?}", res
);
154 assert
!(res
.is_ok());
155 if let Ok((options
, rest
)) = res
{
156 assert
!(options
["enable"] == true);
157 assert
!(rest
.len() == 0);
161 //Ok((options, rest)) => {