avoid static references
This commit is contained in:
parent
331ab992d7
commit
0dde2f04d0
45
src/api3.rs
45
src/api3.rs
|
@ -7,20 +7,6 @@ use crate::api_info::*;
|
||||||
use serde_json::{json, Value};
|
use serde_json::{json, Value};
|
||||||
|
|
||||||
|
|
||||||
static GET: ApiMethod = ApiMethod {
|
|
||||||
handler: test_api_handler,
|
|
||||||
description: "This is a simple test.",
|
|
||||||
parameters: &Object!{
|
|
||||||
properties => &propertymap!{
|
|
||||||
force => &Boolean!{
|
|
||||||
optional => Some(true),
|
|
||||||
description => "Test for boolean options."
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
returns: &Jss::Null,
|
|
||||||
};
|
|
||||||
|
|
||||||
fn test_api_handler(param: Value) -> Result<Value, Error> {
|
fn test_api_handler(param: Value) -> Result<Value, Error> {
|
||||||
println!("This is a test {}", param);
|
println!("This is a test {}", param);
|
||||||
|
|
||||||
|
@ -39,22 +25,23 @@ fn test_api_handler(param: Value) -> Result<Value, Error> {
|
||||||
Ok(json!(null))
|
Ok(json!(null))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_api_definition() -> MethodInfo {
|
|
||||||
|
|
||||||
let subdir1 = methodinfo!{
|
pub fn router() -> MethodInfo {
|
||||||
get => &GET
|
|
||||||
};
|
|
||||||
|
|
||||||
let info = methodinfo!{
|
|
||||||
get => &GET,
|
|
||||||
subdirs => {
|
|
||||||
let mut map = HashMap::new();
|
|
||||||
|
|
||||||
map.insert(String::from("subdir"), subdir1);
|
let route = MethodInfo::new()
|
||||||
|
.get(ApiMethod {
|
||||||
map
|
handler: test_api_handler,
|
||||||
}
|
description: "This is a simple test.",
|
||||||
};
|
parameters: parameter!{
|
||||||
|
force => Boolean!{
|
||||||
|
optional => Some(true),
|
||||||
|
description => "Test for boolean options."
|
||||||
|
}
|
||||||
|
},
|
||||||
|
returns: Jss::Null,
|
||||||
|
});
|
||||||
|
|
||||||
info
|
route
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -6,25 +6,40 @@ use serde_json::{Value};
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct ApiMethod<'a> {
|
pub struct ApiMethod {
|
||||||
pub description: &'a str,
|
pub description: &'static str,
|
||||||
pub parameters: &'a Jss<'a>,
|
pub parameters: Jss,
|
||||||
pub returns: &'a Jss<'a>,
|
pub returns: Jss,
|
||||||
pub handler: fn(Value) -> Result<Value, Error>,
|
pub handler: fn(Value) -> Result<Value, Error>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct MethodInfo {
|
pub struct MethodInfo {
|
||||||
pub get: Option<&'static ApiMethod<'static>>,
|
pub get: Option<ApiMethod>,
|
||||||
pub put: Option<&'static ApiMethod<'static>>,
|
pub put: Option<ApiMethod>,
|
||||||
pub post: Option<&'static ApiMethod<'static>>,
|
pub post: Option<ApiMethod>,
|
||||||
pub delete: Option<&'static ApiMethod<'static>>,
|
pub delete: Option<ApiMethod>,
|
||||||
pub subdirs: Option<HashMap<String, MethodInfo>>,
|
pub subdirs: Option<HashMap<String, MethodInfo>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl MethodInfo {
|
impl MethodInfo {
|
||||||
|
|
||||||
pub fn find_method<'a>(&'a self, components: &[&str]) -> Option<&'a MethodInfo> {
|
pub fn new() -> Self {
|
||||||
|
Self {
|
||||||
|
get: None,
|
||||||
|
put: None,
|
||||||
|
post: None,
|
||||||
|
delete: None,
|
||||||
|
subdirs: None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get(mut self, m: ApiMethod) -> Self {
|
||||||
|
self.get = Some(m);
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn find_method(&self, components: &[&str]) -> Option<&MethodInfo> {
|
||||||
|
|
||||||
if components.len() == 0 { return Some(self); };
|
if components.len() == 0 { return Some(self); };
|
||||||
|
|
||||||
|
@ -40,20 +55,16 @@ impl MethodInfo {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub const METHOD_INFO_DEFAULTS: MethodInfo = MethodInfo {
|
// fixme: remove - not required?
|
||||||
get: None,
|
|
||||||
put: None,
|
|
||||||
post: None,
|
|
||||||
delete: None,
|
|
||||||
subdirs: None,
|
|
||||||
};
|
|
||||||
|
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! methodinfo {
|
macro_rules! methodinfo {
|
||||||
($($option:ident => $e:expr),*) => {
|
($($option:ident => $e:expr),*) => {{
|
||||||
MethodInfo {
|
let info = MethodInfo::new();
|
||||||
$( $option: Some($e), )*
|
|
||||||
..METHOD_INFO_DEFAULTS
|
$(
|
||||||
};
|
info.$option = Some($e);
|
||||||
}
|
)*
|
||||||
|
|
||||||
|
info
|
||||||
|
}}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,17 +1,17 @@
|
||||||
use crate::static_map::StaticMap;
|
use std::collections::HashMap;
|
||||||
|
|
||||||
pub type PropertyMap<'a> = StaticMap<'a, &'a str, &'a Jss<'a>>;
|
pub type PropertyMap = HashMap<&'static str, Jss>;
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct JssBoolean<'a> {
|
pub struct JssBoolean {
|
||||||
pub description: &'a str,
|
pub description: &'static str,
|
||||||
pub optional: Option<bool>,
|
pub optional: Option<bool>,
|
||||||
pub default: Option<bool>,
|
pub default: Option<bool>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct JssInteger<'a> {
|
pub struct JssInteger {
|
||||||
pub description: &'a str,
|
pub description: &'static str,
|
||||||
pub optional: Option<bool>,
|
pub optional: Option<bool>,
|
||||||
pub minimum: Option<usize>,
|
pub minimum: Option<usize>,
|
||||||
pub maximum: Option<usize>,
|
pub maximum: Option<usize>,
|
||||||
|
@ -19,37 +19,37 @@ pub struct JssInteger<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct JssString<'a> {
|
pub struct JssString {
|
||||||
pub description: &'a str,
|
pub description: &'static str,
|
||||||
pub optional: Option<bool>,
|
pub optional: Option<bool>,
|
||||||
pub default: Option<&'a str>,
|
pub default: Option<&'static str>,
|
||||||
pub min_length: Option<usize>,
|
pub min_length: Option<usize>,
|
||||||
pub max_length: Option<usize>,
|
pub max_length: Option<usize>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct JssArray<'a> {
|
pub struct JssArray {
|
||||||
pub description: &'a str,
|
pub description: &'static str,
|
||||||
pub optional: Option<bool>,
|
pub optional: Option<bool>,
|
||||||
pub items: &'a Jss<'a>,
|
pub items: Box<Jss>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct JssObject<'a> {
|
pub struct JssObject {
|
||||||
pub description: &'a str,
|
pub description: &'static str,
|
||||||
pub optional: Option<bool>,
|
pub optional: Option<bool>,
|
||||||
pub additional_properties: Option<bool>,
|
pub additional_properties: Option<bool>,
|
||||||
pub properties: &'a PropertyMap<'a>,
|
pub properties: Box<HashMap<&'static str, Jss>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum Jss<'a> {
|
pub enum Jss {
|
||||||
Null,
|
Null,
|
||||||
Boolean(JssBoolean<'a>),
|
Boolean(JssBoolean),
|
||||||
Integer(JssInteger<'a>),
|
Integer(JssInteger),
|
||||||
String(JssString<'a>),
|
String(JssString),
|
||||||
Object(JssObject<'a>),
|
Object(JssObject),
|
||||||
Array(JssArray<'a>),
|
Array(JssArray),
|
||||||
}
|
}
|
||||||
|
|
||||||
pub const DEFAULTBOOL: JssBoolean = JssBoolean {
|
pub const DEFAULTBOOL: JssBoolean = JssBoolean {
|
||||||
|
@ -95,53 +95,45 @@ macro_rules! ApiString {
|
||||||
}}
|
}}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub const DEFAULTARRAY: JssArray = JssArray {
|
|
||||||
description: "",
|
|
||||||
optional: None,
|
|
||||||
items: &Jss::Null, // is this a reasonable default??
|
|
||||||
};
|
|
||||||
|
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! Array {
|
macro_rules! parameter {
|
||||||
($($name:ident => $e:expr),*) => {{
|
($($name:ident => $e:expr),*) => {{
|
||||||
Jss::Array(JssArray { $($name: $e, )* ..DEFAULTARRAY})
|
let inner = JssObject {
|
||||||
}}
|
description: "",
|
||||||
}
|
optional: None,
|
||||||
|
additional_properties: None,
|
||||||
|
properties: {
|
||||||
|
let mut map = HashMap::<&'static str, Jss>::new();
|
||||||
|
$(
|
||||||
|
map.insert(stringify!($name), $e);
|
||||||
|
)*
|
||||||
|
Box::new(map)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
pub const EMPTYOBJECT: PropertyMap = PropertyMap { entries: &[] };
|
Jss::Object(inner)
|
||||||
|
|
||||||
pub const DEFAULTOBJECT: JssObject = JssObject {
|
|
||||||
description: "",
|
|
||||||
optional: None,
|
|
||||||
additional_properties: None,
|
|
||||||
properties: &EMPTYOBJECT, // is this a reasonable default??
|
|
||||||
};
|
|
||||||
|
|
||||||
#[macro_export]
|
|
||||||
macro_rules! Object {
|
|
||||||
($($name:ident => $e:expr),*) => {{
|
|
||||||
Jss::Object(JssObject { $($name: $e, )* ..DEFAULTOBJECT})
|
|
||||||
}}
|
}}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Standard Option Definitions
|
|
||||||
pub static PVE_VMID: Jss = Integer!{
|
|
||||||
description => "The (unique) ID of the VM.",
|
|
||||||
minimum => Some(1)
|
|
||||||
};
|
|
||||||
|
|
||||||
#[macro_export]
|
#[test]
|
||||||
macro_rules! propertymap {
|
fn test_shema1() {
|
||||||
($($name:ident => $e:expr),*) => {
|
let schema = Jss::Object(JssObject {
|
||||||
PropertyMap {
|
description: "TEST",
|
||||||
entries: &[
|
optional: None,
|
||||||
$( ( stringify!($name), $e), )*
|
additional_properties: None,
|
||||||
]
|
properties: {
|
||||||
|
let map = HashMap::new();
|
||||||
|
|
||||||
|
Box::new(map)
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
|
|
||||||
|
println!("TEST Schema: {:?}", schema);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
#[test]
|
#[test]
|
||||||
fn test_shema1() {
|
fn test_shema1() {
|
||||||
static PARAMETERS1: PropertyMap = propertymap!{
|
static PARAMETERS1: PropertyMap = propertymap!{
|
||||||
|
@ -186,3 +178,4 @@ fn test_shema1() {
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
14
src/main.rs
14
src/main.rs
|
@ -59,14 +59,14 @@ fn handle_request(req: Request<Body>) -> Response<Body> {
|
||||||
http_error!(NOT_FOUND, format!("Unsupported format '{}'\n", format))
|
http_error!(NOT_FOUND, format!("Unsupported format '{}'\n", format))
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(info) = API_ROOT.find_method(&components[2..]) {
|
if let Some(info) = ROUTER.find_method(&components[2..]) {
|
||||||
println!("FOUND INFO");
|
println!("FOUND INFO");
|
||||||
let api_method_opt = match method {
|
let api_method_opt = match method {
|
||||||
&Method::GET => info.get,
|
&Method::GET => &info.get,
|
||||||
&Method::PUT => info.put,
|
// &Method::PUT => info.put,
|
||||||
&Method::POST => info.post,
|
// &Method::POST => info.post,
|
||||||
&Method::DELETE => info.delete,
|
// &Method::DELETE => info.delete,
|
||||||
_ => None,
|
_ => &None,
|
||||||
};
|
};
|
||||||
let api_method = match api_method_opt {
|
let api_method = match api_method_opt {
|
||||||
Some(m) => m,
|
Some(m) => m,
|
||||||
|
@ -101,7 +101,7 @@ fn handle_request(req: Request<Body>) -> Response<Body> {
|
||||||
}
|
}
|
||||||
|
|
||||||
lazy_static!{
|
lazy_static!{
|
||||||
static ref API_ROOT: MethodInfo = apitest::api3::get_api_definition();
|
static ref ROUTER: MethodInfo = apitest::api3::router();
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
|
|
Loading…
Reference in New Issue