From 379ea0edb65b8a422332566d3f669cc05883624e Mon Sep 17 00:00:00 2001 From: Dietmar Maurer Date: Sat, 19 Jan 2019 12:53:07 +0100 Subject: [PATCH] Revert "/api/schema.rs: implement Schema::Option" This reverts commit 0a35462c1e3b9429ea9f276ac620af4752919dff. I am not sure this add much value, and the old approach needs less memory. If we really need single optional values, we can still implement such Option while keeping the hash based approach... --- src/api/schema.rs | 41 +++++++++++------------------------------ src/cli/command.rs | 8 ++++---- src/getopts.rs | 2 +- src/section_config.rs | 13 ++++--------- 4 files changed, 20 insertions(+), 44 deletions(-) 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 {