diff --git a/src/api/schema.rs b/src/api/schema.rs index 2cb6c90a..ff360cb0 100644 --- a/src/api/schema.rs +++ b/src/api/schema.rs @@ -249,7 +249,7 @@ impl ArraySchema { pub struct ObjectSchema { pub description: &'static str, pub additional_properties: bool, - pub properties: HashMap<&'static str, Arc>, + pub properties: HashMap<&'static str, (bool, Arc)>, pub default_key: Option<&'static str>, } @@ -276,12 +276,12 @@ impl ObjectSchema { } pub fn required>>(mut self, name: &'static str, schema: S) -> Self { - self.properties.insert(name, schema.into()); + self.properties.insert(name, (false, schema.into())); self } pub fn optional>>(mut self, name: &'static str, schema: S) -> Self { - self.properties.insert(name, Arc::new(Schema::Option(schema.into()))); + self.properties.insert(name, (true, schema.into())); self } } @@ -294,7 +294,6 @@ pub enum Schema { String(StringSchema), Object(ObjectSchema), Array(ArraySchema), - Option(Arc), } impl From for Schema { @@ -454,9 +453,6 @@ pub fn parse_simple_value(value_str: &str, schema: &Schema) -> Result { - parse_simple_value(value_str, option_schema)? - } _ => bail!("unable to parse complex (sub) objects."), }; Ok(value) @@ -474,7 +470,7 @@ pub fn parse_parameter_strings(data: &Vec<(String, String)>, schema: &ObjectSche let additional_properties = schema.additional_properties; for (key, value) in data { - if let Some(prop_schema) = properties.get::(key) { + if let Some((_optional, prop_schema)) = properties.get::(key) { match prop_schema.as_ref() { Schema::Array(array_schema) => { if params[key] == Value::Null { @@ -525,14 +521,9 @@ pub fn parse_parameter_strings(data: &Vec<(String, String)>, schema: &ObjectSche } if test_required && errors.len() == 0 { - for (name, prop_schema) in properties { - match prop_schema.as_ref() { - Schema::Option(_) => {}, - _ => { - if params[name] == Value::Null { - errors.push(format_err!("parameter '{}': parameter is missing and it is not optional.", name)); - } - } + for (name, (optional, _prop_schema)) in properties { + if *optional == false && params[name] == Value::Null { + errors.push(format_err!("parameter '{}': parameter is missing and it is not optional.", name)); } } } @@ -561,11 +552,6 @@ pub fn verify_json(data: &Value, schema: &Schema) -> Result<(), Error> { Schema::Array(array_schema) => { verify_json_array(data, &array_schema)?; } - Schema::Option(option_schema) => { - if !data.is_null() { - verify_json(data, option_schema)?; - } - } Schema::Null => { if !data.is_null() { bail!("Expected Null, but value is not Null."); @@ -630,7 +616,7 @@ pub fn verify_json_object(data: &Value, schema: &ObjectSchema) -> Result<(), Err let additional_properties = schema.additional_properties; for (key, value) in map { - if let Some(prop_schema) = properties.get::(key) { + if let Some((_optional, prop_schema)) = properties.get::(key) { match prop_schema.as_ref() { Schema::Object(object_schema) => { verify_json_object(value, object_schema)?; @@ -647,14 +633,9 @@ pub fn verify_json_object(data: &Value, schema: &ObjectSchema) -> Result<(), Err } } - for (name, prop_schema) in properties { - match prop_schema.as_ref() { - Schema::Option(_) => {}, - _ => { - if data[name] == Value::Null { - bail!("property '{}': property is missing and it is not optional.", name); - } - } + for (name, (optional, _prop_schema)) in properties { + if *optional == false && data[name] == Value::Null { + bail!("property '{}': property is missing and it is not optional.", name); } } diff --git a/src/cli/command.rs b/src/cli/command.rs index 3c36e3da..87143d82 100644 --- a/src/cli/command.rs +++ b/src/cli/command.rs @@ -120,7 +120,7 @@ fn record_done_arguments(done: &mut HashSet, parameters: &ObjectSchema, for arg in list { if arg.starts_with("--") && arg.len() > 2 { let prop_name = arg[2..].to_owned(); - if let Some(schema) = parameters.properties.get::(&prop_name) { + if let Some((_, schema)) = parameters.properties.get::(&prop_name) { match schema.as_ref() { Schema::Array(_) => { /* do nothing */ } _ => { done.insert(prop_name); } @@ -147,7 +147,7 @@ fn print_simple_completion( print_simple_completion(cli_cmd, done, &arg_param[1..], args); return; } else if args.len() == 1 { - if let Some(schema) = cli_cmd.info.parameters.properties.get(prop_name) { + if let Some((_, schema)) = cli_cmd.info.parameters.properties.get(prop_name) { print_property_completion(schema, prop_name, &cli_cmd.completion_functions, &args[0]); } } @@ -164,14 +164,14 @@ fn print_simple_completion( let last = &args[args.len()-1]; if last.starts_with("--") && last.len() > 2 { let prop_name = &last[2..]; - if let Some(schema) = cli_cmd.info.parameters.properties.get(prop_name) { + if let Some((_, schema)) = cli_cmd.info.parameters.properties.get(prop_name) { print_property_completion(schema, prop_name, &cli_cmd.completion_functions, &prefix); } return; } } - for (name, _schema) in &cli_cmd.info.parameters.properties { + for (name, (_optional, _schema)) in &cli_cmd.info.parameters.properties { if done.contains(*name) { continue; } let option = String::from("--") + name; if option.starts_with(&prefix) { diff --git a/src/getopts.rs b/src/getopts.rs index 4a276ca1..1293deec 100644 --- a/src/getopts.rs +++ b/src/getopts.rs @@ -75,7 +75,7 @@ pub fn parse_arguments>( None => { let mut want_bool = false; let mut can_default = false; - if let Some(param_schema) = properties.get::(&name) { + if let Some((_optional, param_schema)) = properties.get::(&name) { if let Schema::Boolean(boolean_schema) = param_schema.as_ref() { want_bool = true; if let Some(default) = boolean_schema.default { diff --git a/src/section_config.rs b/src/section_config.rs index c6a175f7..0a057a73 100644 --- a/src/section_config.rs +++ b/src/section_config.rs @@ -150,14 +150,9 @@ impl SectionConfig { let mut state = ParseState::BeforeHeader; let test_required_properties = |value: &Value, schema: &ObjectSchema| -> Result<(), Error> { - for (name, prop_schema) in &schema.properties { - match prop_schema.as_ref() { - Schema::Option(_) => {}, - _ => { - if value[name] == Value::Null { - return Err(format_err!("property '{}' is missing and it is not optional.", name)); - } - } + for (name, (optional, _prop_schema)) in &schema.properties { + if *optional == false && value[name] == Value::Null { + return Err(format_err!("property '{}' is missing and it is not optional.", name)); } } Ok(()) @@ -209,7 +204,7 @@ impl SectionConfig { if let Some((key, value)) = (self.parse_section_content)(line) { //println!("CONTENT: key: {} value: {}", key, value); - if let Some(prop_schema) = plugin.properties.properties.get::(&key) { + if let Some((_optional, prop_schema)) = plugin.properties.properties.get::(&key) { match parse_simple_value(&value, prop_schema) { Ok(value) => { if config[&key] == Value::Null {