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();
26 if length
== 2 { return RawArgument::Separator; }
30 for start
in first
..length
{
31 if chars
[start
] == '
='
{
32 let name
: String
= chars
[first
..start
].iter().collect();
33 let value
: String
= chars
[start
+1..length
].iter().collect();
34 return RawArgument
::Option { name, value: Some(value) }
38 let name
: String
= chars
[first
..].iter().collect();
39 return RawArgument
::Option { name: name, value: None }
43 RawArgument
::Argument { value: arg.to_string() }
46 pub fn parse_arguments(
48 schema
: &ObjectSchema
,
49 ) -> Result
<(Value
,Vec
<String
>), ParameterError
> {
51 let mut errors
= ParameterError
::new();
53 let properties
= &schema
.properties
;
55 let mut data
: Vec
<(String
, String
)> = vec
![];
56 let mut rest
: Vec
<String
> = vec
![];
64 rest
.push(args
[pos
].clone());
66 match parse_argument(&args
[pos
]) {
67 RawArgument
::Separator
=> {
70 RawArgument
::Option { name, value }
=> {
73 let param_schema
= properties
.get
::<str>(&name
);
74 let (want_bool
, can_default
) = match param_schema
{
75 Some(Schema
::Boolean(boolean_schema
)) => {
76 if let Some(default) = boolean_schema
.default {
77 if default == true { (true, false); }
84 let mut next_is_argument
= false;
85 let mut next_is_bool
= false;
87 if (pos
+ 1) < args
.len() {
88 let next
= &args
[pos
+1];
89 if let RawArgument
::Argument { value: _}
= parse_argument(next
) {
90 next_is_argument
= true;
91 if let Ok(_
) = parse_boolean(next
) { next_is_bool = true; }
98 data
.push((name
, args
[pos
].clone()));
99 } else if can_default
{
100 data
.push((name
, "true".to_string()));
102 errors
.push(format_err
!("parameter '{}': {}", name
,
103 "missing boolean value."));
108 if next_is_argument
{
110 data
.push((name
, args
[pos
].clone()));
112 errors
.push(format_err
!("parameter '{}': {}", name
,
113 "missing parameter value."));
118 data
.push((name
, v
));
122 RawArgument
::Argument { value }
=> {
129 if pos
>= args
.len() { break; }
132 if errors
.len() > 0 { return Err(errors); }
134 let options
= parse_parameter_strings(&data
, schema
, true)?
;
141 fn test_boolean_arg() {
143 let schema
= parameter
!{enable => Boolean!{ optional => false }
};
145 let mut variants
: Vec
<(Vec
<&str>, bool
)> = vec
![];
146 variants
.push((vec
!["-enable"], true));
147 variants
.push((vec
!["-enable=1"], true));
148 variants
.push((vec
!["-enable", "yes"], true));
149 variants
.push((vec
!["-enable", "Yes"], true));
150 variants
.push((vec
!["--enable", "1"], true));
151 variants
.push((vec
!["--enable", "ON"], true));
152 variants
.push((vec
!["--enable", "true"], true));
154 variants
.push((vec
!["--enable", "0"], false));
155 variants
.push((vec
!["--enable", "no"], false));
156 variants
.push((vec
!["--enable", "off"], false));
157 variants
.push((vec
!["--enable", "false"], false));
159 for (args
, expect
) in variants
{
160 let string_args
= args
.iter().map(|s
| s
.to_string()).collect();
161 let res
= parse_arguments(&string_args
, &schema
);
162 assert
!(res
.is_ok());
163 if let Ok((options
, rest
)) = res
{
164 assert
!(options
["enable"] == expect
);
165 assert
!(rest
.len() == 0);