From 29af28ad8d37769a0033f46eec0e35ff42fcbb85 Mon Sep 17 00:00:00 2001 From: Dominic Date: Mon, 30 Sep 2019 18:18:10 +0200 Subject: [PATCH] the example compiles :party: --- examples/users.rs | 7 ++-- src/lib.rs | 4 +++ src/openapi.rs | 88 +++++++++++++++++++++++------------------------ src/routing.rs | 8 ++--- 4 files changed, 56 insertions(+), 51 deletions(-) diff --git a/examples/users.rs b/examples/users.rs index 1cfe938..fd8caac 100644 --- a/examples/users.rs +++ b/examples/users.rs @@ -125,9 +125,12 @@ fn main() .add(logging) .build() ); - + gotham::start(ADDR, build_router(chain, pipelines, |route| { - route.resource::("users"); + route.with_openapi("Users Example", "0.0.1", |mut route| { + route.resource::("users"); + route.get_openapi("openapi"); + }); })); println!("Gotham started on {} for testing", ADDR); } diff --git a/src/lib.rs b/src/lib.rs index e83d213..8bbdab3 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -5,6 +5,8 @@ pub use hyper::StatusCode; #[cfg(feature = "openapi")] pub mod openapi; +#[cfg(feature = "openapi")] +pub use openapi::{GetOpenapi, OpenapiRouter}; mod resource; pub use resource::{ @@ -23,3 +25,5 @@ pub use result::{ResourceResult, Success}; mod routing; pub use routing::{DrawResources, DrawResourceRoutes}; +#[cfg(feature = "openapi")] +pub use routing::WithOpenapi; diff --git a/src/openapi.rs b/src/openapi.rs index 43e947d..d5aff5f 100644 --- a/src/openapi.rs +++ b/src/openapi.rs @@ -18,43 +18,36 @@ use openapiv3::{MediaType, OpenAPI, Operation, PathItem, Paths, ReferenceOr, Ref use serde::de::DeserializeOwned; use std::panic::RefUnwindSafe; -pub struct OpenapiRouter<'a, D> -{ - route : &'a mut D, - openapi : OpenAPI -} +pub struct OpenapiRouter(OpenAPI); -impl<'a, D> OpenapiRouter<'a, D> +impl OpenapiRouter { - pub fn new(route : &'a mut D, title : Title, version : Version) -> Self + pub fn new<Title : ToString, Version : ToString>(title : Title, version : Version) -> Self { - Self { - route, - openapi: OpenAPI { - openapi: "3.0.2".to_string(), - info: openapiv3::Info { - title: title.to_string(), - description: None, - terms_of_service: None, - contact: None, - license: None, - version: version.to_string() - }, - servers: Vec::new(), - paths: Paths::new(), - components: None, - security: Vec::new(), - tags: Vec::new(), - external_docs: None - } - } + Self(OpenAPI { + openapi: "3.0.2".to_string(), + info: openapiv3::Info { + title: title.to_string(), + description: None, + terms_of_service: None, + contact: None, + license: None, + version: version.to_string() + }, + servers: Vec::new(), + paths: Paths::new(), + components: None, + security: Vec::new(), + tags: Vec::new(), + external_docs: None + }) } /// Remove path from the OpenAPI spec, or return an empty one if not included. This is handy if you need to /// modify the path and add it back after the modification fn remove_path(&mut self, path : &str) -> PathItem { - if let Some(Item(item)) = self.openapi.paths.swap_remove(path) + if let Some(Item(item)) = self.0.paths.swap_remove(path) { return item; } @@ -74,7 +67,7 @@ impl<'a, D> OpenapiRouter<'a, D> fn add_path<Path : ToString>(&mut self, path : Path, item : PathItem) { - self.openapi.paths.insert(path.to_string(), Item(item)); + self.0.paths.insert(path.to_string(), Item(item)); } } @@ -86,9 +79,9 @@ impl RefUnwindSafe for OpenapiHandler {} impl OpenapiHandler { - fn new(openapi : &OpenAPI) -> Self + fn new(openapi : &OpenapiRouter) -> Self { - Self(serde_json::to_string(openapi).map_err(|e| format!("{}", e))) + Self(serde_json::to_string(&openapi.0).map_err(|e| format!("{}", e))) } } @@ -120,21 +113,26 @@ impl Handler for OpenapiHandler } } +pub trait GetOpenapi +{ + fn get_openapi(&mut self, path : &str); +} + macro_rules! implOpenapiRouter { ($implType:ident) => { - impl<'a, C, P> OpenapiRouter<'a, $implType<'a, C, P>> + impl<'a, C, P> GetOpenapi for (&mut $implType<'a, C, P>, &mut OpenapiRouter) where C : PipelineHandleChain<P> + Copy + Send + Sync + 'static, P : RefUnwindSafe + Send + Sync + 'static { - pub fn get_openapi(&mut self, path : &str) + fn get_openapi(&mut self, path : &str) { - self.route.get(path).to_new_handler(OpenapiHandler::new(&self.openapi)); + self.0.get(path).to_new_handler(OpenapiHandler::new(&self.1)); } } - impl<'a, C, P> DrawResources for OpenapiRouter<'a, $implType<'a, C, P>> + impl<'a, C, P> DrawResources for (&mut $implType<'a, C, P>, &mut OpenapiRouter) where C : PipelineHandleChain<P> + Copy + Send + Sync + 'static, P : RefUnwindSafe + Send + Sync + 'static @@ -145,7 +143,7 @@ macro_rules! implOpenapiRouter { } } - impl<'a, C, P> DrawResourceRoutes for (&mut OpenapiRouter<'a, $implType<'a, C, P>>, String) + impl<'a, C, P> DrawResourceRoutes for (&mut (&mut $implType<'a, C, P>, &mut OpenapiRouter), String) where C : PipelineHandleChain<P> + Copy + Send + Sync + 'static, P : RefUnwindSafe + Send + Sync + 'static @@ -156,7 +154,7 @@ macro_rules! implOpenapiRouter { Handler : ResourceReadAll<Res> { let path = &self.1; - let mut item = self.0.remove_path(path); + let mut item = (self.0).1.remove_path(path); let mut content : IndexMap<String, MediaType> = IndexMap::new(); content[&APPLICATION_JSON.to_string()] = MediaType { schema: None, // TODO @@ -187,9 +185,9 @@ macro_rules! implOpenapiRouter { security: Vec::new(), servers: Vec::new() }); - self.0.add_path(path, item); + (self.0).1.add_path(path, item); - (&mut *self.0.route, self.1.to_string()).read_all::<Handler, Res>() + (&mut *(self.0).0, self.1.to_string()).read_all::<Handler, Res>() } fn read<Handler, ID, Res>(&mut self) @@ -198,7 +196,7 @@ macro_rules! implOpenapiRouter { Res : ResourceResult, Handler : ResourceRead<ID, Res> { - (&mut *self.0.route, self.1.to_string()).read::<Handler, ID, Res>() + (&mut *(self.0).0, self.1.to_string()).read::<Handler, ID, Res>() } fn create<Handler, Body, Res>(&mut self) @@ -207,7 +205,7 @@ macro_rules! implOpenapiRouter { Res : ResourceResult, Handler : ResourceCreate<Body, Res> { - (&mut *self.0.route, self.1.to_string()).create::<Handler, Body, Res>() + (&mut *(self.0).0, self.1.to_string()).create::<Handler, Body, Res>() } fn update_all<Handler, Body, Res>(&mut self) @@ -216,7 +214,7 @@ macro_rules! implOpenapiRouter { Res : ResourceResult, Handler : ResourceUpdateAll<Body, Res> { - (&mut *self.0.route, self.1.to_string()).update_all::<Handler, Body, Res>() + (&mut *(self.0).0, self.1.to_string()).update_all::<Handler, Body, Res>() } fn update<Handler, ID, Body, Res>(&mut self) @@ -226,7 +224,7 @@ macro_rules! implOpenapiRouter { Res : ResourceResult, Handler : ResourceUpdate<ID, Body, Res> { - (&mut *self.0.route, self.1.to_string()).update::<Handler, ID, Body, Res>() + (&mut *(self.0).0, self.1.to_string()).update::<Handler, ID, Body, Res>() } fn delete_all<Handler, Res>(&mut self) @@ -234,7 +232,7 @@ macro_rules! implOpenapiRouter { Res : ResourceResult, Handler : ResourceDeleteAll<Res> { - (&mut *self.0.route, self.1.to_string()).delete_all::<Handler, Res>() + (&mut *(self.0).0, self.1.to_string()).delete_all::<Handler, Res>() } fn delete<Handler, ID, Res>(&mut self) @@ -243,7 +241,7 @@ macro_rules! implOpenapiRouter { Res : ResourceResult, Handler : ResourceDelete<ID, Res> { - (&mut *self.0.route, self.1.to_string()).delete::<Handler, ID, Res>() + (&mut *(self.0).0, self.1.to_string()).delete::<Handler, ID, Res>() } } diff --git a/src/routing.rs b/src/routing.rs index f4fdbd5..ae073a9 100644 --- a/src/routing.rs +++ b/src/routing.rs @@ -36,7 +36,7 @@ pub trait WithOpenapi<D> { fn with_openapi<F, Title, Version>(&mut self, title : Title, version : Version, block : F) where - F : FnOnce(OpenapiRouter<D>), + F : FnOnce((&mut D, &mut OpenapiRouter)), Title : ToString, Version : ToString; } @@ -237,12 +237,12 @@ macro_rules! implDrawResourceRoutes { { fn with_openapi<F, Title, Version>(&mut self, title : Title, version : Version, block : F) where - F : FnOnce(OpenapiRouter<Self>), + F : FnOnce((&mut Self, &mut OpenapiRouter)), Title : ToString, Version : ToString { - let router : OpenapiRouter<Self> = OpenapiRouter::new(self, title, version); - block(router); + let mut router = OpenapiRouter::new(title, version); + block((self, &mut router)); } }