start using builder pattern instead of macros
This commit is contained in:
parent
dc454ef096
commit
82df76fff0
@ -27,7 +27,7 @@ impl Registry {
|
|||||||
|
|
||||||
pub fn register_format(&mut self, name: &'static str, format: ApiStringFormat) {
|
pub fn register_format(&mut self, name: &'static str, format: ApiStringFormat) {
|
||||||
|
|
||||||
if let Some(format) = self.formats.get(name) {
|
if let Some(_format) = self.formats.get(name) {
|
||||||
panic!("standard format '{}' already registered.", name); // fixme: really panic?
|
panic!("standard format '{}' already registered.", name); // fixme: really panic?
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -42,13 +42,13 @@ impl Registry {
|
|||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn register_option(&mut self, name: &'static str, schema: Schema) {
|
pub fn register_option<S: Into<Schema>>(&mut self, name: &'static str, schema: S) {
|
||||||
|
|
||||||
if let Some(schema) = self.options.get(name) {
|
if let Some(_schema) = self.options.get(name) {
|
||||||
panic!("standard option '{}' already registered.", name); // fixme: really panic?
|
panic!("standard option '{}' already registered.", name); // fixme: really panic?
|
||||||
}
|
}
|
||||||
|
|
||||||
self.options.insert(name, Arc::new(schema));
|
self.options.insert(name, Arc::new(schema.into()));
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn lookup_option(&self, name: &str) -> Option<Arc<Schema>> {
|
pub fn lookup_option(&self, name: &str) -> Option<Arc<Schema>> {
|
||||||
@ -69,18 +69,16 @@ impl Registry {
|
|||||||
|
|
||||||
self.register_option(
|
self.register_option(
|
||||||
"pve-vmid",
|
"pve-vmid",
|
||||||
Integer!{
|
IntegerSchema::new("The (unique) ID of the VM.")
|
||||||
description => "The (unique) ID of the VM.",
|
.minimum(1)
|
||||||
minimum => Some(1),
|
.optional(false)
|
||||||
optional => false
|
);
|
||||||
});
|
|
||||||
|
|
||||||
self.register_option(
|
self.register_option(
|
||||||
"pve-node",
|
"pve-node",
|
||||||
ApiString!{
|
StringSchema::new("The cluster node name.")
|
||||||
description => "The cluster node name.",
|
.format(self.lookup_format("pve-node").unwrap()) //fixme: unwrap?
|
||||||
format => self.lookup_format("pve-node")
|
);
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -45,6 +45,31 @@ pub struct BooleanSchema {
|
|||||||
pub default: Option<bool>,
|
pub default: Option<bool>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl BooleanSchema {
|
||||||
|
|
||||||
|
pub fn new(description: &'static str) -> Self {
|
||||||
|
BooleanSchema {
|
||||||
|
description: description,
|
||||||
|
optional: false,
|
||||||
|
default: None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn optional(mut self, optional: bool) -> Self {
|
||||||
|
self.optional = optional;
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn default(mut self, default: bool) -> Self {
|
||||||
|
self.default = Some(default);
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn arc(self) -> Arc<Schema> {
|
||||||
|
Arc::new(self.into())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct IntegerSchema {
|
pub struct IntegerSchema {
|
||||||
pub description: &'static str,
|
pub description: &'static str,
|
||||||
@ -54,6 +79,44 @@ pub struct IntegerSchema {
|
|||||||
pub default: Option<isize>,
|
pub default: Option<isize>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl IntegerSchema {
|
||||||
|
|
||||||
|
pub fn new(description: &'static str) -> Self {
|
||||||
|
IntegerSchema {
|
||||||
|
description: description,
|
||||||
|
optional: false,
|
||||||
|
default: None,
|
||||||
|
minimum: None,
|
||||||
|
maximum: None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn optional(mut self, optional: bool) -> Self {
|
||||||
|
self.optional = optional;
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn default(mut self, default: isize) -> Self {
|
||||||
|
self.default = Some(default);
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn minimum(mut self, minimum: isize) -> Self {
|
||||||
|
self.minimum = Some(minimum);
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn maximum(mut self, maximium: isize) -> Self {
|
||||||
|
self.maximum = Some(maximium);
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn arc(self) -> Arc<Schema> {
|
||||||
|
Arc::new(self.into())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct StringSchema {
|
pub struct StringSchema {
|
||||||
pub description: &'static str,
|
pub description: &'static str,
|
||||||
@ -64,6 +127,49 @@ pub struct StringSchema {
|
|||||||
pub format: Option<Arc<ApiStringFormat>>,
|
pub format: Option<Arc<ApiStringFormat>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl StringSchema {
|
||||||
|
|
||||||
|
pub fn new(description: &'static str) -> Self {
|
||||||
|
StringSchema {
|
||||||
|
description: description,
|
||||||
|
optional: false,
|
||||||
|
default: None,
|
||||||
|
min_length: None,
|
||||||
|
max_length: None,
|
||||||
|
format: None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn optional(mut self, optional: bool) -> Self {
|
||||||
|
self.optional = optional;
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn default(mut self, text: &'static str) -> Self {
|
||||||
|
self.default = Some(text);
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn format(mut self, format: Arc<ApiStringFormat>) -> Self {
|
||||||
|
self.format = Some(format);
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn min_length(mut self, min_length: usize) -> Self {
|
||||||
|
self.min_length = Some(min_length);
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn max_length(mut self, max_length: usize) -> Self {
|
||||||
|
self.max_length = Some(max_length);
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn arc(self) -> Arc<Schema> {
|
||||||
|
Arc::new(self.into())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct ArraySchema {
|
pub struct ArraySchema {
|
||||||
pub description: &'static str,
|
pub description: &'static str,
|
||||||
@ -89,42 +195,23 @@ pub enum Schema {
|
|||||||
Array(ArraySchema),
|
Array(ArraySchema),
|
||||||
}
|
}
|
||||||
|
|
||||||
pub const DEFAULTBOOL: BooleanSchema = BooleanSchema {
|
impl From<StringSchema> for Schema {
|
||||||
description: "",
|
fn from(string_schema: StringSchema) -> Self {
|
||||||
optional: false,
|
Schema::String(string_schema)
|
||||||
default: None,
|
}
|
||||||
};
|
|
||||||
|
|
||||||
#[macro_export]
|
|
||||||
macro_rules! Boolean {
|
|
||||||
($($name:ident => $e:expr),*) => {{
|
|
||||||
Schema::Boolean(BooleanSchema { $($name: $e, )* ..DEFAULTBOOL})
|
|
||||||
}}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub const DEFAULTINTEGER: IntegerSchema = IntegerSchema {
|
impl From<BooleanSchema> for Schema {
|
||||||
description: "",
|
fn from(boolean_schema: BooleanSchema) -> Self {
|
||||||
optional: false,
|
Schema::Boolean(boolean_schema)
|
||||||
default: None,
|
}
|
||||||
minimum: None,
|
|
||||||
maximum: None,
|
|
||||||
};
|
|
||||||
|
|
||||||
#[macro_export]
|
|
||||||
macro_rules! Integer {
|
|
||||||
($($name:ident => $e:expr),*) => {{
|
|
||||||
Schema::Integer(IntegerSchema { $($name: $e, )* ..DEFAULTINTEGER})
|
|
||||||
}}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub const DEFAULTSTRING: StringSchema = StringSchema {
|
impl From<IntegerSchema> for Schema {
|
||||||
description: "",
|
fn from(integer_schema: IntegerSchema) -> Self {
|
||||||
optional: false,
|
Schema::Integer(integer_schema)
|
||||||
default: None,
|
}
|
||||||
min_length: None,
|
}
|
||||||
max_length: None,
|
|
||||||
format: None,
|
|
||||||
};
|
|
||||||
|
|
||||||
pub enum ApiStringFormat {
|
pub enum ApiStringFormat {
|
||||||
Enum(Vec<String>),
|
Enum(Vec<String>),
|
||||||
@ -152,13 +239,6 @@ impl std::fmt::Debug for ApiStringFormat {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[macro_export]
|
|
||||||
macro_rules! ApiString {
|
|
||||||
($($name:ident => $e:expr),*) => {{
|
|
||||||
Schema::String(StringSchema { $($name: $e, )* ..DEFAULTSTRING})
|
|
||||||
}}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! parameter {
|
macro_rules! parameter {
|
||||||
@ -377,24 +457,25 @@ fn test_schema1() {
|
|||||||
#[test]
|
#[test]
|
||||||
fn test_query_string() {
|
fn test_query_string() {
|
||||||
|
|
||||||
let schema = parameter!{name => Arc::new(ApiString!{ optional => false })};
|
let schema = parameter!{name => StringSchema::new("Name.").optional(false).arc()};
|
||||||
|
|
||||||
let res = parse_query_string("", &schema, true);
|
let res = parse_query_string("", &schema, true);
|
||||||
assert!(res.is_err());
|
assert!(res.is_err());
|
||||||
|
|
||||||
let schema = parameter!{name => Arc::new(ApiString!{ optional => true })};
|
let schema = parameter!{name => StringSchema::new("Name.").optional(true).arc()};
|
||||||
|
|
||||||
let res = parse_query_string("", &schema, true);
|
let res = parse_query_string("", &schema, true);
|
||||||
assert!(res.is_ok());
|
assert!(res.is_ok());
|
||||||
|
|
||||||
// TEST min_length and max_length
|
// TEST min_length and max_length
|
||||||
|
|
||||||
let schema = parameter!{name => Arc::new(ApiString!{
|
let schema = parameter!{
|
||||||
optional => false,
|
name => StringSchema::new("Name.")
|
||||||
min_length => Some(5),
|
.optional(false)
|
||||||
max_length => Some(10)
|
.min_length(5)
|
||||||
|
.max_length(10)
|
||||||
})};
|
.arc()
|
||||||
|
};
|
||||||
|
|
||||||
let res = parse_query_string("name=abcd", &schema, true);
|
let res = parse_query_string("name=abcd", &schema, true);
|
||||||
assert!(res.is_err());
|
assert!(res.is_err());
|
||||||
@ -410,10 +491,12 @@ fn test_query_string() {
|
|||||||
|
|
||||||
// TEST regex pattern
|
// TEST regex pattern
|
||||||
|
|
||||||
let schema = parameter!{name => Arc::new(ApiString!{
|
let schema = parameter!{
|
||||||
optional => false,
|
name => StringSchema::new("Name.")
|
||||||
format => Some(Arc::new(ApiStringFormat::Pattern(Box::new(Regex::new("test").unwrap()))))
|
.optional(false)
|
||||||
})};
|
.format(Arc::new(ApiStringFormat::Pattern(Box::new(Regex::new("test").unwrap()))))
|
||||||
|
.arc()
|
||||||
|
};
|
||||||
|
|
||||||
let res = parse_query_string("name=abcd", &schema, true);
|
let res = parse_query_string("name=abcd", &schema, true);
|
||||||
assert!(res.is_err());
|
assert!(res.is_err());
|
||||||
@ -421,10 +504,12 @@ fn test_query_string() {
|
|||||||
let res = parse_query_string("name=ateststring", &schema, true);
|
let res = parse_query_string("name=ateststring", &schema, true);
|
||||||
assert!(res.is_ok());
|
assert!(res.is_ok());
|
||||||
|
|
||||||
let schema = parameter!{name => Arc::new(ApiString!{
|
let schema = parameter!{
|
||||||
optional => false,
|
name => StringSchema::new("Name.")
|
||||||
format => Some(Arc::new(ApiStringFormat::Pattern(Box::new(Regex::new("^test$").unwrap()))))
|
.optional(false)
|
||||||
})};
|
.format(Arc::new(ApiStringFormat::Pattern(Box::new(Regex::new("^test$").unwrap()))))
|
||||||
|
.arc()
|
||||||
|
};
|
||||||
|
|
||||||
let res = parse_query_string("name=ateststring", &schema, true);
|
let res = parse_query_string("name=ateststring", &schema, true);
|
||||||
assert!(res.is_err());
|
assert!(res.is_err());
|
||||||
@ -434,10 +519,12 @@ fn test_query_string() {
|
|||||||
|
|
||||||
// TEST string enums
|
// TEST string enums
|
||||||
|
|
||||||
let schema = parameter!{name => Arc::new(ApiString!{
|
let schema = parameter!{
|
||||||
optional => false,
|
name => StringSchema::new("Name.")
|
||||||
format => Some(Arc::new(ApiStringFormat::Enum(vec!["ev1".into(), "ev2".into()])))
|
.optional(false)
|
||||||
})};
|
.format(Arc::new(ApiStringFormat::Enum(vec!["ev1".into(), "ev2".into()])))
|
||||||
|
.arc()
|
||||||
|
};
|
||||||
|
|
||||||
let res = parse_query_string("name=noenum", &schema, true);
|
let res = parse_query_string("name=noenum", &schema, true);
|
||||||
assert!(res.is_err());
|
assert!(res.is_err());
|
||||||
@ -456,16 +543,18 @@ fn test_query_string() {
|
|||||||
#[test]
|
#[test]
|
||||||
fn test_query_integer() {
|
fn test_query_integer() {
|
||||||
|
|
||||||
let schema = parameter!{count => Arc::new(Integer!{ optional => false })};
|
let schema = parameter!{count => IntegerSchema::new("Count.").optional(false).arc()};
|
||||||
|
|
||||||
let res = parse_query_string("", &schema, true);
|
let res = parse_query_string("", &schema, true);
|
||||||
assert!(res.is_err());
|
assert!(res.is_err());
|
||||||
|
|
||||||
let schema = parameter!{count => Arc::new(Integer!{
|
let schema = parameter!{
|
||||||
optional => true,
|
count => IntegerSchema::new("Count.")
|
||||||
minimum => Some(-3),
|
.optional(true)
|
||||||
maximum => Some(50)
|
.minimum(-3)
|
||||||
})};
|
.maximum(50)
|
||||||
|
.arc()
|
||||||
|
};
|
||||||
|
|
||||||
let res = parse_query_string("", &schema, true);
|
let res = parse_query_string("", &schema, true);
|
||||||
assert!(res.is_ok());
|
assert!(res.is_ok());
|
||||||
@ -495,12 +584,12 @@ fn test_query_integer() {
|
|||||||
#[test]
|
#[test]
|
||||||
fn test_query_boolean() {
|
fn test_query_boolean() {
|
||||||
|
|
||||||
let schema = parameter!{force => Arc::new(Boolean!{ optional => false })};
|
let schema = parameter!{force => BooleanSchema::new("Force.").optional(false).arc()};
|
||||||
|
|
||||||
let res = parse_query_string("", &schema, true);
|
let res = parse_query_string("", &schema, true);
|
||||||
assert!(res.is_err());
|
assert!(res.is_err());
|
||||||
|
|
||||||
let schema = parameter!{force => Arc::new(Boolean!{ optional => true })};
|
let schema = parameter!{force => BooleanSchema::new("Force.").optional(true).arc()};
|
||||||
|
|
||||||
let res = parse_query_string("", &schema, true);
|
let res = parse_query_string("", &schema, true);
|
||||||
assert!(res.is_ok());
|
assert!(res.is_ok());
|
||||||
|
@ -45,10 +45,9 @@ pub fn router() -> Router {
|
|||||||
handler: test_sync_api_handler,
|
handler: test_sync_api_handler,
|
||||||
description: "This is a simple test.",
|
description: "This is a simple test.",
|
||||||
parameters: parameter!{
|
parameters: parameter!{
|
||||||
force => Arc::new(Boolean!{
|
force => BooleanSchema::new("Test for boolean options")
|
||||||
optional => true,
|
.optional(true)
|
||||||
description => "Test for boolean options."
|
.arc()
|
||||||
})
|
|
||||||
},
|
},
|
||||||
returns: Schema::Null,
|
returns: Schema::Null,
|
||||||
})
|
})
|
||||||
|
@ -156,7 +156,7 @@ pub fn parse_arguments(
|
|||||||
#[test]
|
#[test]
|
||||||
fn test_boolean_arg() {
|
fn test_boolean_arg() {
|
||||||
|
|
||||||
let schema = parameter!{enable => Arc::new(Boolean!{ optional => false })};
|
let schema = parameter!{enable => BooleanSchema::new("Enable").optional(false).arc()};
|
||||||
|
|
||||||
let mut variants: Vec<(Vec<&str>, bool)> = vec![];
|
let mut variants: Vec<(Vec<&str>, bool)> = vec![];
|
||||||
variants.push((vec!["-enable"], true));
|
variants.push((vec!["-enable"], true));
|
||||||
@ -187,8 +187,8 @@ fn test_boolean_arg() {
|
|||||||
fn test_argument_paramenter() {
|
fn test_argument_paramenter() {
|
||||||
|
|
||||||
let schema = parameter!{
|
let schema = parameter!{
|
||||||
enable => Arc::new(Boolean!{ optional => false }),
|
enable => BooleanSchema::new("Enable.").optional(false).arc(),
|
||||||
storage => Arc::new(ApiString!{ optional => false })
|
storage => StringSchema::new("Storatge:").optional(false).arc()
|
||||||
};
|
};
|
||||||
|
|
||||||
let args = vec!["-enable", "local"];
|
let args = vec!["-enable", "local"];
|
||||||
|
@ -20,7 +20,9 @@ use hyper;
|
|||||||
fn main() {
|
fn main() {
|
||||||
println!("Proxmox REST Server example.");
|
println!("Proxmox REST Server example.");
|
||||||
|
|
||||||
let prop = Arc::new(ApiString!{ optional => true });
|
let prop = StringSchema::new("This is a test").arc();
|
||||||
|
|
||||||
|
//let prop = Arc::new(ApiString!{ optional => true });
|
||||||
let schema = parameter!{
|
let schema = parameter!{
|
||||||
name1 => prop.clone(),
|
name1 => prop.clone(),
|
||||||
name2 => prop.clone()
|
name2 => prop.clone()
|
||||||
|
Loading…
Reference in New Issue
Block a user