Revert "/api/schema.rs: implement Schema::Option"

This reverts commit 0a35462c1e.

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...
This commit is contained in:
Dietmar Maurer 2019-01-19 12:53:07 +01:00
parent 80f069656d
commit 379ea0edb6
4 changed files with 20 additions and 44 deletions

View File

@ -249,7 +249,7 @@ impl ArraySchema {
pub struct ObjectSchema { pub struct ObjectSchema {
pub description: &'static str, pub description: &'static str,
pub additional_properties: bool, pub additional_properties: bool,
pub properties: HashMap<&'static str, Arc<Schema>>, pub properties: HashMap<&'static str, (bool, Arc<Schema>)>,
pub default_key: Option<&'static str>, pub default_key: Option<&'static str>,
} }
@ -276,12 +276,12 @@ impl ObjectSchema {
} }
pub fn required<S: Into<Arc<Schema>>>(mut self, name: &'static str, schema: S) -> Self { pub fn required<S: Into<Arc<Schema>>>(mut self, name: &'static str, schema: S) -> Self {
self.properties.insert(name, schema.into()); self.properties.insert(name, (false, schema.into()));
self self
} }
pub fn optional<S: Into<Arc<Schema>>>(mut self, name: &'static str, schema: S) -> Self { pub fn optional<S: Into<Arc<Schema>>>(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 self
} }
} }
@ -294,7 +294,6 @@ pub enum Schema {
String(StringSchema), String(StringSchema),
Object(ObjectSchema), Object(ObjectSchema),
Array(ArraySchema), Array(ArraySchema),
Option(Arc<Schema>),
} }
impl From<StringSchema> for Schema { impl From<StringSchema> for Schema {
@ -454,9 +453,6 @@ pub fn parse_simple_value(value_str: &str, schema: &Schema) -> Result<Value, Err
string_schema.check_constraints(value_str)?; string_schema.check_constraints(value_str)?;
Value::String(value_str.into()) Value::String(value_str.into())
} }
Schema::Option(option_schema) => {
parse_simple_value(value_str, option_schema)?
}
_ => bail!("unable to parse complex (sub) objects."), _ => bail!("unable to parse complex (sub) objects."),
}; };
Ok(value) Ok(value)
@ -474,7 +470,7 @@ pub fn parse_parameter_strings(data: &Vec<(String, String)>, schema: &ObjectSche
let additional_properties = schema.additional_properties; let additional_properties = schema.additional_properties;
for (key, value) in data { for (key, value) in data {
if let Some(prop_schema) = properties.get::<str>(key) { if let Some((_optional, prop_schema)) = properties.get::<str>(key) {
match prop_schema.as_ref() { match prop_schema.as_ref() {
Schema::Array(array_schema) => { Schema::Array(array_schema) => {
if params[key] == Value::Null { if params[key] == Value::Null {
@ -525,17 +521,12 @@ pub fn parse_parameter_strings(data: &Vec<(String, String)>, schema: &ObjectSche
} }
if test_required && errors.len() == 0 { if test_required && errors.len() == 0 {
for (name, prop_schema) in properties { for (name, (optional, _prop_schema)) in properties {
match prop_schema.as_ref() { if *optional == false && params[name] == Value::Null {
Schema::Option(_) => {},
_ => {
if params[name] == Value::Null {
errors.push(format_err!("parameter '{}': parameter is missing and it is not optional.", name)); errors.push(format_err!("parameter '{}': parameter is missing and it is not optional.", name));
} }
} }
} }
}
}
if errors.len() > 0 { if errors.len() > 0 {
Err(errors) Err(errors)
@ -561,11 +552,6 @@ pub fn verify_json(data: &Value, schema: &Schema) -> Result<(), Error> {
Schema::Array(array_schema) => { Schema::Array(array_schema) => {
verify_json_array(data, &array_schema)?; verify_json_array(data, &array_schema)?;
} }
Schema::Option(option_schema) => {
if !data.is_null() {
verify_json(data, option_schema)?;
}
}
Schema::Null => { Schema::Null => {
if !data.is_null() { if !data.is_null() {
bail!("Expected Null, but value is not 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; let additional_properties = schema.additional_properties;
for (key, value) in map { for (key, value) in map {
if let Some(prop_schema) = properties.get::<str>(key) { if let Some((_optional, prop_schema)) = properties.get::<str>(key) {
match prop_schema.as_ref() { match prop_schema.as_ref() {
Schema::Object(object_schema) => { Schema::Object(object_schema) => {
verify_json_object(value, object_schema)?; verify_json_object(value, object_schema)?;
@ -647,16 +633,11 @@ pub fn verify_json_object(data: &Value, schema: &ObjectSchema) -> Result<(), Err
} }
} }
for (name, prop_schema) in properties { for (name, (optional, _prop_schema)) in properties {
match prop_schema.as_ref() { if *optional == false && data[name] == Value::Null {
Schema::Option(_) => {},
_ => {
if data[name] == Value::Null {
bail!("property '{}': property is missing and it is not optional.", name); bail!("property '{}': property is missing and it is not optional.", name);
} }
} }
}
}
Ok(()) Ok(())
} }

View File

@ -120,7 +120,7 @@ fn record_done_arguments(done: &mut HashSet<String>, parameters: &ObjectSchema,
for arg in list { for arg in list {
if arg.starts_with("--") && arg.len() > 2 { if arg.starts_with("--") && arg.len() > 2 {
let prop_name = arg[2..].to_owned(); let prop_name = arg[2..].to_owned();
if let Some(schema) = parameters.properties.get::<str>(&prop_name) { if let Some((_, schema)) = parameters.properties.get::<str>(&prop_name) {
match schema.as_ref() { match schema.as_ref() {
Schema::Array(_) => { /* do nothing */ } Schema::Array(_) => { /* do nothing */ }
_ => { done.insert(prop_name); } _ => { done.insert(prop_name); }
@ -147,7 +147,7 @@ fn print_simple_completion(
print_simple_completion(cli_cmd, done, &arg_param[1..], args); print_simple_completion(cli_cmd, done, &arg_param[1..], args);
return; return;
} else if args.len() == 1 { } 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]); 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]; let last = &args[args.len()-1];
if last.starts_with("--") && last.len() > 2 { if last.starts_with("--") && last.len() > 2 {
let prop_name = &last[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); print_property_completion(schema, prop_name, &cli_cmd.completion_functions, &prefix);
} }
return; 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; } if done.contains(*name) { continue; }
let option = String::from("--") + name; let option = String::from("--") + name;
if option.starts_with(&prefix) { if option.starts_with(&prefix) {

View File

@ -75,7 +75,7 @@ pub fn parse_arguments<T: AsRef<str>>(
None => { None => {
let mut want_bool = false; let mut want_bool = false;
let mut can_default = false; let mut can_default = false;
if let Some(param_schema) = properties.get::<str>(&name) { if let Some((_optional, param_schema)) = properties.get::<str>(&name) {
if let Schema::Boolean(boolean_schema) = param_schema.as_ref() { if let Schema::Boolean(boolean_schema) = param_schema.as_ref() {
want_bool = true; want_bool = true;
if let Some(default) = boolean_schema.default { if let Some(default) = boolean_schema.default {

View File

@ -150,16 +150,11 @@ impl SectionConfig {
let mut state = ParseState::BeforeHeader; let mut state = ParseState::BeforeHeader;
let test_required_properties = |value: &Value, schema: &ObjectSchema| -> Result<(), Error> { let test_required_properties = |value: &Value, schema: &ObjectSchema| -> Result<(), Error> {
for (name, prop_schema) in &schema.properties { for (name, (optional, _prop_schema)) in &schema.properties {
match prop_schema.as_ref() { if *optional == false && value[name] == Value::Null {
Schema::Option(_) => {},
_ => {
if value[name] == Value::Null {
return Err(format_err!("property '{}' is missing and it is not optional.", name)); return Err(format_err!("property '{}' is missing and it is not optional.", name));
} }
} }
}
}
Ok(()) Ok(())
}; };
@ -209,7 +204,7 @@ impl SectionConfig {
if let Some((key, value)) = (self.parse_section_content)(line) { if let Some((key, value)) = (self.parse_section_content)(line) {
//println!("CONTENT: key: {} value: {}", key, value); //println!("CONTENT: key: {} value: {}", key, value);
if let Some(prop_schema) = plugin.properties.properties.get::<str>(&key) { if let Some((_optional, prop_schema)) = plugin.properties.properties.get::<str>(&key) {
match parse_simple_value(&value, prop_schema) { match parse_simple_value(&value, prop_schema) {
Ok(value) => { Ok(value) => {
if config[&key] == Value::Null { if config[&key] == Value::Null {