From 0dde2f04d02e40aec7ffbcb1e50ea53d26cc6f2e Mon Sep 17 00:00:00 2001 From: Dietmar Maurer Date: Sat, 3 Nov 2018 15:10:21 +0100 Subject: [PATCH] avoid static references --- src/api3.rs | 45 +++++++------------ src/api_info.rs | 57 ++++++++++++++---------- src/json_schema.rs | 107 +++++++++++++++++++++------------------------ src/main.rs | 14 +++--- 4 files changed, 107 insertions(+), 116 deletions(-) diff --git a/src/api3.rs b/src/api3.rs index 5723fd83..96fb5bf4 100644 --- a/src/api3.rs +++ b/src/api3.rs @@ -7,20 +7,6 @@ use crate::api_info::*; 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 { println!("This is a test {}", param); @@ -39,22 +25,23 @@ fn test_api_handler(param: Value) -> Result { Ok(json!(null)) } -pub fn get_api_definition() -> MethodInfo { - let subdir1 = methodinfo!{ - get => &GET - }; - - let info = methodinfo!{ - get => &GET, - subdirs => { - let mut map = HashMap::new(); +pub fn router() -> MethodInfo { - map.insert(String::from("subdir"), subdir1); - - map - } - }; + let route = MethodInfo::new() + .get(ApiMethod { + 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 } + + diff --git a/src/api_info.rs b/src/api_info.rs index 521f6f4e..ab2a92d8 100644 --- a/src/api_info.rs +++ b/src/api_info.rs @@ -6,25 +6,40 @@ use serde_json::{Value}; use std::collections::HashMap; #[derive(Debug)] -pub struct ApiMethod<'a> { - pub description: &'a str, - pub parameters: &'a Jss<'a>, - pub returns: &'a Jss<'a>, +pub struct ApiMethod { + pub description: &'static str, + pub parameters: Jss, + pub returns: Jss, pub handler: fn(Value) -> Result, } #[derive(Debug)] pub struct MethodInfo { - pub get: Option<&'static ApiMethod<'static>>, - pub put: Option<&'static ApiMethod<'static>>, - pub post: Option<&'static ApiMethod<'static>>, - pub delete: Option<&'static ApiMethod<'static>>, + pub get: Option, + pub put: Option, + pub post: Option, + pub delete: Option, pub subdirs: Option>, } 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); }; @@ -40,20 +55,16 @@ impl MethodInfo { } } -pub const METHOD_INFO_DEFAULTS: MethodInfo = MethodInfo { - get: None, - put: None, - post: None, - delete: None, - subdirs: None, -}; - +// fixme: remove - not required? #[macro_export] macro_rules! methodinfo { - ($($option:ident => $e:expr),*) => { - MethodInfo { - $( $option: Some($e), )* - ..METHOD_INFO_DEFAULTS - }; - } + ($($option:ident => $e:expr),*) => {{ + let info = MethodInfo::new(); + + $( + info.$option = Some($e); + )* + + info + }} } diff --git a/src/json_schema.rs b/src/json_schema.rs index 0fcd7684..6e7d7eb6 100644 --- a/src/json_schema.rs +++ b/src/json_schema.rs @@ -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)] -pub struct JssBoolean<'a> { - pub description: &'a str, +pub struct JssBoolean { + pub description: &'static str, pub optional: Option, pub default: Option, } #[derive(Debug)] -pub struct JssInteger<'a> { - pub description: &'a str, +pub struct JssInteger { + pub description: &'static str, pub optional: Option, pub minimum: Option, pub maximum: Option, @@ -19,37 +19,37 @@ pub struct JssInteger<'a> { } #[derive(Debug)] -pub struct JssString<'a> { - pub description: &'a str, +pub struct JssString { + pub description: &'static str, pub optional: Option, - pub default: Option<&'a str>, + pub default: Option<&'static str>, pub min_length: Option, pub max_length: Option, } #[derive(Debug)] -pub struct JssArray<'a> { - pub description: &'a str, +pub struct JssArray { + pub description: &'static str, pub optional: Option, - pub items: &'a Jss<'a>, + pub items: Box, } #[derive(Debug)] -pub struct JssObject<'a> { - pub description: &'a str, +pub struct JssObject { + pub description: &'static str, pub optional: Option, pub additional_properties: Option, - pub properties: &'a PropertyMap<'a>, + pub properties: Box>, } #[derive(Debug)] -pub enum Jss<'a> { +pub enum Jss { Null, - Boolean(JssBoolean<'a>), - Integer(JssInteger<'a>), - String(JssString<'a>), - Object(JssObject<'a>), - Array(JssArray<'a>), + Boolean(JssBoolean), + Integer(JssInteger), + String(JssString), + Object(JssObject), + Array(JssArray), } 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_rules! Array { +macro_rules! parameter { ($($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: &[] }; - -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}) + Jss::Object(inner) }} } -// Standard Option Definitions -pub static PVE_VMID: Jss = Integer!{ - description => "The (unique) ID of the VM.", - minimum => Some(1) -}; -#[macro_export] -macro_rules! propertymap { - ($($name:ident => $e:expr),*) => { - PropertyMap { - entries: &[ - $( ( stringify!($name), $e), )* - ] +#[test] +fn test_shema1() { + let schema = Jss::Object(JssObject { + description: "TEST", + optional: None, + additional_properties: None, + properties: { + let map = HashMap::new(); + + Box::new(map) } - } + }); + + println!("TEST Schema: {:?}", schema); } +/* #[test] fn test_shema1() { static PARAMETERS1: PropertyMap = propertymap!{ @@ -186,3 +178,4 @@ fn test_shema1() { } +*/ diff --git a/src/main.rs b/src/main.rs index 7bf5f4e7..9f203dbe 100644 --- a/src/main.rs +++ b/src/main.rs @@ -59,14 +59,14 @@ fn handle_request(req: Request) -> Response { 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"); let api_method_opt = match method { - &Method::GET => info.get, - &Method::PUT => info.put, - &Method::POST => info.post, - &Method::DELETE => info.delete, - _ => None, + &Method::GET => &info.get, + // &Method::PUT => info.put, + // &Method::POST => info.post, + // &Method::DELETE => info.delete, + _ => &None, }; let api_method = match api_method_opt { Some(m) => m, @@ -101,7 +101,7 @@ fn handle_request(req: Request) -> Response { } lazy_static!{ - static ref API_ROOT: MethodInfo = apitest::api3::get_api_definition(); + static ref ROUTER: MethodInfo = apitest::api3::router(); } fn main() {