/api/schema.rs: implement Schema::Option
This commit is contained in:
parent
fdb95d92dd
commit
0a35462c1e
@ -251,7 +251,7 @@ impl ArraySchema {
|
||||
pub struct ObjectSchema {
|
||||
pub description: &'static str,
|
||||
pub additional_properties: bool,
|
||||
pub properties: HashMap<&'static str, (bool, Arc<Schema>)>,
|
||||
pub properties: HashMap<&'static str, Arc<Schema>>,
|
||||
pub default_key: Option<&'static str>,
|
||||
}
|
||||
|
||||
@ -278,12 +278,12 @@ impl ObjectSchema {
|
||||
}
|
||||
|
||||
pub fn required<S: Into<Arc<Schema>>>(mut self, name: &'static str, schema: S) -> Self {
|
||||
self.properties.insert(name, (false, schema.into()));
|
||||
self.properties.insert(name, schema.into());
|
||||
self
|
||||
}
|
||||
|
||||
pub fn optional<S: Into<Arc<Schema>>>(mut self, name: &'static str, schema: S) -> Self {
|
||||
self.properties.insert(name, (true, schema.into()));
|
||||
self.properties.insert(name, Arc::new(Schema::Option(schema.into())));
|
||||
self
|
||||
}
|
||||
}
|
||||
@ -296,6 +296,7 @@ pub enum Schema {
|
||||
String(StringSchema),
|
||||
Object(ObjectSchema),
|
||||
Array(ArraySchema),
|
||||
Option(Arc<Schema>),
|
||||
}
|
||||
|
||||
impl From<StringSchema> for Schema {
|
||||
@ -455,6 +456,9 @@ pub fn parse_simple_value(value_str: &str, schema: &Schema) -> Result<Value, Err
|
||||
string_schema.check_constraints(value_str)?;
|
||||
Value::String(value_str.into())
|
||||
}
|
||||
Schema::Option(option_schema) => {
|
||||
parse_simple_value(value_str, option_schema)?
|
||||
}
|
||||
_ => bail!("unable to parse complex (sub) objects."),
|
||||
};
|
||||
Ok(value)
|
||||
@ -472,7 +476,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((_optional, prop_schema)) = properties.get::<str>(key) {
|
||||
if let Some(prop_schema) = properties.get::<str>(key) {
|
||||
match prop_schema.as_ref() {
|
||||
Schema::Array(array_schema) => {
|
||||
if params[key] == Value::Null {
|
||||
@ -523,12 +527,17 @@ pub fn parse_parameter_strings(data: &Vec<(String, String)>, schema: &ObjectSche
|
||||
}
|
||||
|
||||
if test_required && errors.len() == 0 {
|
||||
for (name, (optional, _prop_schema)) in properties {
|
||||
if *optional == false && params[name] == Value::Null {
|
||||
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));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if errors.len() > 0 {
|
||||
Err(errors)
|
||||
@ -554,6 +563,11 @@ 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.");
|
||||
@ -618,7 +632,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((_optional, prop_schema)) = properties.get::<str>(key) {
|
||||
if let Some(prop_schema) = properties.get::<str>(key) {
|
||||
match prop_schema.as_ref() {
|
||||
Schema::Object(object_schema) => {
|
||||
verify_json_object(value, object_schema)?;
|
||||
@ -635,11 +649,16 @@ pub fn verify_json_object(data: &Value, schema: &ObjectSchema) -> Result<(), Err
|
||||
}
|
||||
}
|
||||
|
||||
for (name, (optional, _prop_schema)) in properties {
|
||||
if *optional == false && data[name] == Value::Null {
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
@ -120,7 +120,7 @@ fn record_done_arguments(done: &mut HashSet<String>, 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::<str>(&prop_name) {
|
||||
if let Some(schema) = parameters.properties.get::<str>(&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, (_optional, _schema)) in &cli_cmd.info.parameters.properties {
|
||||
for (name, _schema) in &cli_cmd.info.parameters.properties {
|
||||
if done.contains(*name) { continue; }
|
||||
let option = String::from("--") + name;
|
||||
if option.starts_with(&prefix) {
|
||||
|
@ -75,7 +75,7 @@ pub fn parse_arguments<T: AsRef<str>>(
|
||||
None => {
|
||||
let mut want_bool = false;
|
||||
let mut can_default = false;
|
||||
if let Some((_optional, param_schema)) = properties.get::<str>(&name) {
|
||||
if let Some(param_schema) = properties.get::<str>(&name) {
|
||||
if let Schema::Boolean(boolean_schema) = param_schema.as_ref() {
|
||||
want_bool = true;
|
||||
if let Some(default) = boolean_schema.default {
|
||||
|
@ -150,11 +150,16 @@ impl SectionConfig {
|
||||
let mut state = ParseState::BeforeHeader;
|
||||
|
||||
let test_required_properties = |value: &Value, schema: &ObjectSchema| -> Result<(), Error> {
|
||||
for (name, (optional, _prop_schema)) in &schema.properties {
|
||||
if *optional == false && value[name] == Value::Null {
|
||||
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));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
};
|
||||
|
||||
@ -204,7 +209,7 @@ impl SectionConfig {
|
||||
if let Some((key, value)) = (self.parse_section_content)(line) {
|
||||
//println!("CONTENT: key: {} value: {}", key, value);
|
||||
|
||||
if let Some((_optional, prop_schema)) = plugin.properties.properties.get::<str>(&key) {
|
||||
if let Some(prop_schema) = plugin.properties.properties.get::<str>(&key) {
|
||||
match parse_simple_value(&value, prop_schema) {
|
||||
Ok(value) => {
|
||||
if config[&key] == Value::Null {
|
||||
|
Loading…
Reference in New Issue
Block a user