diff --git a/src/api/schema.rs b/src/api/schema.rs index 2644827a..c4319260 100644 --- a/src/api/schema.rs +++ b/src/api/schema.rs @@ -4,6 +4,7 @@ use serde_json::{json, Value}; use url::form_urlencoded; use regex::Regex; use std::fmt; +use std::sync::Arc; pub type PropertyMap = HashMap<&'static str, Schema>; @@ -67,7 +68,7 @@ pub struct StringSchema { pub struct ArraySchema { pub description: &'static str, pub optional: bool, - pub items: Box, + pub items: Arc, } #[derive(Debug)] @@ -75,7 +76,7 @@ pub struct ObjectSchema { pub description: &'static str, pub optional: bool, pub additional_properties: bool, - pub properties: HashMap<&'static str, Schema>, + pub properties: HashMap<&'static str, Arc>, } #[derive(Debug)] @@ -130,7 +131,7 @@ pub enum ApiStringFormat { None, Enum(Vec), Pattern(Box), - Complex(Box), + Complex(Arc), } #[macro_export] @@ -148,7 +149,7 @@ macro_rules! parameter { description: "", optional: false, additional_properties: false, - properties: HashMap::<&'static str, Schema>::new(), + properties: HashMap::<&'static str, Arc>::new(), } }}; ($($name:ident => $e:expr),*) => {{ @@ -157,7 +158,7 @@ macro_rules! parameter { optional: false, additional_properties: false, properties: { - let mut map = HashMap::<&'static str, Schema>::new(); + let mut map = HashMap::<&'static str, Arc>::new(); $( map.insert(stringify!($name), $e); )* @@ -255,7 +256,7 @@ pub fn parse_parameter_strings(data: &Vec<(String, String)>, schema: &ObjectSche for (key, value) in data { if let Some(prop_schema) = properties.get::(key) { - match prop_schema { + match prop_schema.as_ref() { Schema::Array(array_schema) => { if params[key] == Value::Null { params[key] = json!([]); @@ -306,7 +307,7 @@ pub fn parse_parameter_strings(data: &Vec<(String, String)>, schema: &ObjectSche if test_required && errors.len() == 0 { for (name, prop_schema) in properties { - let optional = match prop_schema { + let optional = match prop_schema.as_ref() { Schema::Boolean(boolean_schema) => boolean_schema.optional, Schema::Integer(integer_schema) => integer_schema.optional, Schema::String(string_schema) => string_schema.optional, @@ -354,24 +355,24 @@ fn test_schema1() { #[test] fn test_query_string() { - let schema = parameter!{name => ApiString!{ optional => false }}; + let schema = parameter!{name => Arc::new(ApiString!{ optional => false })}; let res = parse_query_string("", &schema, true); assert!(res.is_err()); - let schema = parameter!{name => ApiString!{ optional => true }}; + let schema = parameter!{name => Arc::new(ApiString!{ optional => true })}; let res = parse_query_string("", &schema, true); assert!(res.is_ok()); // TEST min_length and max_length - let schema = parameter!{name => ApiString!{ + let schema = parameter!{name => Arc::new(ApiString!{ optional => false, min_length => Some(5), max_length => Some(10) - }}; + })}; let res = parse_query_string("name=abcd", &schema, true); assert!(res.is_err()); @@ -387,10 +388,10 @@ fn test_query_string() { // TEST regex pattern - let schema = parameter!{name => ApiString!{ + let schema = parameter!{name => Arc::new(ApiString!{ optional => false, format => ApiStringFormat::Pattern(Box::new(Regex::new("test").unwrap())) - }}; + })}; let res = parse_query_string("name=abcd", &schema, true); assert!(res.is_err()); @@ -398,10 +399,10 @@ fn test_query_string() { let res = parse_query_string("name=ateststring", &schema, true); assert!(res.is_ok()); - let schema = parameter!{name => ApiString!{ + let schema = parameter!{name => Arc::new(ApiString!{ optional => false, format => ApiStringFormat::Pattern(Box::new(Regex::new("^test$").unwrap())) - }}; + })}; let res = parse_query_string("name=ateststring", &schema, true); assert!(res.is_err()); @@ -411,10 +412,10 @@ fn test_query_string() { // TEST string enums - let schema = parameter!{name => ApiString!{ + let schema = parameter!{name => Arc::new(ApiString!{ optional => false, format => ApiStringFormat::Enum(vec!["ev1".into(), "ev2".into()]) - }}; + })}; let res = parse_query_string("name=noenum", &schema, true); assert!(res.is_err()); @@ -433,16 +434,16 @@ fn test_query_string() { #[test] fn test_query_integer() { - let schema = parameter!{count => Integer!{ optional => false }}; + let schema = parameter!{count => Arc::new(Integer!{ optional => false })}; let res = parse_query_string("", &schema, true); assert!(res.is_err()); - let schema = parameter!{count => Integer!{ + let schema = parameter!{count => Arc::new(Integer!{ optional => true, minimum => Some(-3), maximum => Some(50) - }}; + })}; let res = parse_query_string("", &schema, true); assert!(res.is_ok()); @@ -472,12 +473,12 @@ fn test_query_integer() { #[test] fn test_query_boolean() { - let schema = parameter!{force => Boolean!{ optional => false }}; + let schema = parameter!{force => Arc::new(Boolean!{ optional => false })}; let res = parse_query_string("", &schema, true); assert!(res.is_err()); - let schema = parameter!{force => Boolean!{ optional => true }}; + let schema = parameter!{force => Arc::new(Boolean!{ optional => true })}; let res = parse_query_string("", &schema, true); assert!(res.is_ok()); diff --git a/src/api3.rs b/src/api3.rs index 9c5fec07..abc97134 100644 --- a/src/api3.rs +++ b/src/api3.rs @@ -1,5 +1,6 @@ use failure::*; use std::collections::HashMap; +use std::sync::Arc; use crate::api::schema::*; @@ -44,10 +45,10 @@ pub fn router() -> Router { handler: test_sync_api_handler, description: "This is a simple test.", parameters: parameter!{ - force => Boolean!{ + force => Arc::new(Boolean!{ optional => true, description => "Test for boolean options." - } + }) }, returns: Schema::Null, }) diff --git a/src/getopts.rs b/src/getopts.rs index fe3e844e..0628f581 100644 --- a/src/getopts.rs +++ b/src/getopts.rs @@ -2,6 +2,8 @@ use crate::api::schema::*; use failure::*; use std::collections::HashMap; +use std::sync::Arc; + use serde_json::{json, Value}; #[derive(Debug)] @@ -71,16 +73,18 @@ pub fn parse_arguments( RawArgument::Option { name, value } => { match value { None => { - let param_schema = properties.get::(&name); - let (want_bool, can_default) = match param_schema { - Some(Schema::Boolean(boolean_schema)) => { + let mut want_bool = false; + let mut can_default = false; + if let Some(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 { - if default == true { (true, false); } + if default == false { can_default = true; } + } else { + can_default = true; } - (true, true) } - _ => (false, false), - }; + } let mut next_is_argument = false; let mut next_is_bool = false; @@ -152,7 +156,7 @@ pub fn parse_arguments( #[test] fn test_boolean_arg() { - let schema = parameter!{enable => Boolean!{ optional => false }}; + let schema = parameter!{enable => Arc::new(Boolean!{ optional => false })}; let mut variants: Vec<(Vec<&str>, bool)> = vec![]; variants.push((vec!["-enable"], true)); @@ -183,8 +187,8 @@ fn test_boolean_arg() { fn test_argument_paramenter() { let schema = parameter!{ - enable => Boolean!{ optional => false }, - storage => ApiString!{ optional => false } + enable => Arc::new(Boolean!{ optional => false }), + storage => Arc::new(ApiString!{ optional => false }) }; let args = vec!["-enable", "local"]; diff --git a/src/main.rs b/src/main.rs index 58af18ac..9c97bfde 100644 --- a/src/main.rs +++ b/src/main.rs @@ -2,6 +2,7 @@ extern crate apitest; use std::collections::HashMap; +use std::sync::Arc; use apitest::api::schema::*; use apitest::api::router::*; @@ -20,7 +21,7 @@ fn main() { println!("Proxmox REST Server example."); let schema = parameter!{ - name => ApiString!{ optional => true } + name => Arc::new(ApiString!{ optional => true }) }; let args: Vec = std::env::args().skip(1).collect();