diff --git a/Cargo.toml b/Cargo.toml index e9dc676a..395155d3 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -5,17 +5,18 @@ authors = ["Dietmar Maurer "] [lib] -name = "json_schema" +name = "apitest" path = "src/lib.rs" version = "0.1.0" authors = ["Dietmar Maurer "] [dependencies] -failure = "0.1.3" -phf = "0.7.23" -phf_macros = "0.7.23" -derive-new = "0.5.5" -serde = "1.0.80" # A generic serialization/deserialization framework -serde_json = "1.0.32" # A JSON serialization file format +failure = "0.1.3" +phf = "0.7.23" +phf_macros = "0.7.23" +derive-new = "0.5.5" +serde = "1.0.80" +serde_json = "1.0.32" serde_derive = "1.0.80" +hyper = "0.12.13" diff --git a/src/api_info.rs b/src/api_info.rs new file mode 100644 index 00000000..4fa8f924 --- /dev/null +++ b/src/api_info.rs @@ -0,0 +1,30 @@ +use failure::*; + +use json_schema::*; +use serde_json::{json, Value}; + +pub struct ApiMethod { + pub description: &'static str, + pub properties: StaticPropertyMap, + pub returns: Jss, + pub handler: fn(Value) -> Result, +} + +pub type StaticSubdirMap = phf::Map<&'static str, &'static MethodInfo>; + +pub struct MethodInfo { + pub get: Option<&'static ApiMethod>, + pub put: Option<&'static ApiMethod>, + pub post: Option<&'static ApiMethod>, + pub delete: Option<&'static ApiMethod>, + pub subdirs: Option<&'static StaticSubdirMap>, +} + +pub static METHOD_INFO_DEFAULTS: MethodInfo = MethodInfo { + get: None, + put: None, + post: None, + delete: None, + subdirs: None, +}; + diff --git a/src/json_schema.rs b/src/json_schema.rs new file mode 100644 index 00000000..1df78fa5 --- /dev/null +++ b/src/json_schema.rs @@ -0,0 +1,132 @@ +pub type StaticPropertyMap = phf::Map<&'static str, Jss>; + +#[derive(Debug)] +pub struct JssBoolean { + pub description: &'static str, + pub optional: Option, + pub default: Option, +} + +#[derive(Debug)] +pub struct JssInteger { + pub description: &'static str, + pub optional: Option, + pub minimum: Option, + pub maximum: Option, + pub default: Option, +} + +#[derive(Debug)] +pub struct JssString { + pub description: &'static str, + pub optional: Option, + pub default: Option<&'static str>, + pub min_length: Option, + pub max_length: Option, +} + +#[derive(Debug)] +pub struct JssArray { + pub description: &'static str, + pub optional: Option, + pub items: &'static Jss, +} + +#[derive(Debug)] +pub struct JssObject { + pub description: &'static str, + pub optional: Option, + pub additional_properties: Option, + pub properties: &'static StaticPropertyMap, +} + +#[derive(Debug)] +pub enum Jss { + Null, + Boolean(JssBoolean), + Integer(JssInteger), + String(JssString), + Object(JssObject), + Array(JssArray), + Reference { reference: &'static Jss }, +} + +pub static DEFAULTBOOL: JssBoolean = JssBoolean { + description: "", + optional: None, + default: None, +}; + +#[macro_export] +macro_rules! Boolean { + ($($name:ident => $e:expr),*) => {{ + Jss::Boolean(JssBoolean { $($name: $e, )* ..DEFAULTBOOL}) + }} +} + +pub static DEFAULTINTEGER: JssInteger = JssInteger { + description: "", + optional: None, + default: None, + minimum: None, + maximum: None, +}; + +#[macro_export] +macro_rules! Integer { + ($($name:ident => $e:expr),*) => {{ + Jss::Integer(JssInteger { $($name: $e, )* ..DEFAULTINTEGER}) + }} +} + +pub static DEFAULTSTRING: JssString = JssString { + description: "", + optional: None, + default: None, + min_length: None, + max_length: None, +}; + +#[macro_export] +macro_rules! ApiString { + ($($name:ident => $e:expr),*) => {{ + Jss::String(JssString { $($name: $e, )* ..DEFAULTSTRING}) + }} +} + +pub static DEFAULTARRAY: JssArray = JssArray { + description: "", + optional: None, + items: &Jss::Null, // is this a reasonable default?? +}; + +#[macro_export] +macro_rules! Array { + ($($name:ident => $e:expr),*) => {{ + Jss::Array(JssArray { $($name: $e, )* ..DEFAULTARRAY}) + }} +} + +pub static EMPTYOBJECT: StaticPropertyMap = phf_map!{}; + +pub static 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) +}; + diff --git a/src/lib.rs b/src/lib.rs index 4d4da188..2b109ce1 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,143 +1,16 @@ #![feature(plugin)] #![plugin(phf_macros)] -//extern crate failure; +extern crate failure; extern crate phf; +extern crate serde_json; + // Jss => JavaScript Schema //use failure::Error; -pub type StaticPropertyMap = phf::Map<&'static str, Jss>; - -#[derive(Debug)] -pub struct JssBoolean { - pub description: &'static str, - pub optional: Option, - pub default: Option, -} - -#[derive(Debug)] -pub struct JssInteger { - pub description: &'static str, - pub optional: Option, - pub minimum: Option, - pub maximum: Option, - pub default: Option, -} - -#[derive(Debug)] -pub struct JssString { - pub description: &'static str, - pub optional: Option, - pub default: Option<&'static str>, - pub min_length: Option, - pub max_length: Option, -} - -#[derive(Debug)] -pub struct JssArray { - pub description: &'static str, - pub optional: Option, - pub items: &'static Jss, -} - -#[derive(Debug)] -pub struct JssObject { - pub description: &'static str, - pub optional: Option, - pub additional_properties: Option, - pub properties: &'static StaticPropertyMap, -} - -#[derive(Debug)] -pub enum Jss { - Null, - Boolean(JssBoolean), - Integer(JssInteger), - String(JssString), - Object(JssObject), - Array(JssArray), - Reference { reference: &'static Jss }, -} - -pub static DEFAULTBOOL: JssBoolean = JssBoolean { - description: "", - optional: None, - default: None, -}; - -#[macro_export] -macro_rules! Boolean { - ($($name:ident => $e:expr),*) => {{ - Jss::Boolean(JssBoolean { $($name: $e, )* ..DEFAULTBOOL}) - }} -} - -pub static DEFAULTINTEGER: JssInteger = JssInteger { - description: "", - optional: None, - default: None, - minimum: None, - maximum: None, -}; - -#[macro_export] -macro_rules! Integer { - ($($name:ident => $e:expr),*) => {{ - Jss::Integer(JssInteger { $($name: $e, )* ..DEFAULTINTEGER}) - }} -} - -pub static DEFAULTSTRING: JssString = JssString { - description: "", - optional: None, - default: None, - min_length: None, - max_length: None, -}; - -#[macro_export] -macro_rules! ApiString { - ($($name:ident => $e:expr),*) => {{ - Jss::String(JssString { $($name: $e, )* ..DEFAULTSTRING}) - }} -} - -pub static DEFAULTARRAY: JssArray = JssArray { - description: "", - optional: None, - items: &Jss::Null, // is this a reasonable default?? -}; - -#[macro_export] -macro_rules! Array { - ($($name:ident => $e:expr),*) => {{ - Jss::Array(JssArray { $($name: $e, )* ..DEFAULTARRAY}) - }} -} - -pub static EMPTYOBJECT: StaticPropertyMap = phf_map!{}; - -pub static 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) -}; +pub mod json_schema; +pub mod api_info; diff --git a/src/main.rs b/src/main.rs index 3e564578..feedcc19 100644 --- a/src/main.rs +++ b/src/main.rs @@ -5,8 +5,12 @@ extern crate phf; extern crate failure; use failure::*; -extern crate json_schema; -use json_schema::*; +#[macro_use] +extern crate apitest; + +use apitest::json_schema::*; +use apitest::api_info::*; + extern crate serde_json; #[macro_use] @@ -14,6 +18,11 @@ extern crate serde_derive; use serde_json::{json, Value}; +extern crate hyper; + +use hyper::{Body, Request, Response, Server}; +use hyper::rt::Future; +use hyper::service::service_fn_ok; static PARAMETERS1: StaticPropertyMap = phf_map! { "force" => Boolean!{ @@ -52,12 +61,6 @@ static PARAMETERS1: StaticPropertyMap = phf_map! { }; -struct ApiMethod { - description: &'static str, - properties: StaticPropertyMap, - returns: Jss, - handler: fn(Value) -> Result, -} #[derive(Serialize, Deserialize)] struct Myparam { @@ -95,26 +98,29 @@ static TEST_API_METHOD: ApiMethod = ApiMethod { handler: test_api_handler, }; -type StaticSubdirMap = phf::Map<&'static str, &'static MethodInfo>; - -struct MethodInfo { - path: &'static str, - get: Option<&'static ApiMethod>, - subdirs: Option<&'static StaticSubdirMap>, -} static API3_NODES: MethodInfo = MethodInfo { - path: "", get: Some(&TEST_API_METHOD), - subdirs: None, + ..METHOD_INFO_DEFAULTS }; static API3: MethodInfo = MethodInfo { - path: "", get: Some(&TEST_API_METHOD), subdirs: Some(&phf_map!{"nodes" => &API3_NODES}), + ..METHOD_INFO_DEFAULTS }; + +fn hello_world(req: Request) -> Response { + + let method = req.method(); + let path = req.uri().path(); + + println!("REQUEST {} {}", method, path); + + Response::new(Body::from("hello World!\n")) +} + fn main() { println!("Fast Static Type Definitions 1"); @@ -122,4 +128,17 @@ fn main() { println!("Parameter: {} Value: {:?}", k, v); } + let addr = ([127, 0, 0, 1], 8007).into(); + + let new_svc = || { + // service_fn_ok converts our function into a `Service` + service_fn_ok(hello_world) + }; + + let server = Server::bind(&addr) + .serve(new_svc) + .map_err(|e| eprintln!("server error: {}", e)); + + // Run this server for... forever! + hyper::rt::run(server); }