mirror of
https://gitlab.com/msrd0/gotham-restful.git
synced 2025-02-23 13:02:28 +00:00
the example compiles :party:
This commit is contained in:
parent
8b0d655ebb
commit
29af28ad8d
4 changed files with 56 additions and 51 deletions
|
@ -127,7 +127,10 @@ fn main()
|
||||||
);
|
);
|
||||||
|
|
||||||
gotham::start(ADDR, build_router(chain, pipelines, |route| {
|
gotham::start(ADDR, build_router(chain, pipelines, |route| {
|
||||||
route.resource::<Users, _>("users");
|
route.with_openapi("Users Example", "0.0.1", |mut route| {
|
||||||
|
route.resource::<Users, _>("users");
|
||||||
|
route.get_openapi("openapi");
|
||||||
|
});
|
||||||
}));
|
}));
|
||||||
println!("Gotham started on {} for testing", ADDR);
|
println!("Gotham started on {} for testing", ADDR);
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,6 +5,8 @@ pub use hyper::StatusCode;
|
||||||
|
|
||||||
#[cfg(feature = "openapi")]
|
#[cfg(feature = "openapi")]
|
||||||
pub mod openapi;
|
pub mod openapi;
|
||||||
|
#[cfg(feature = "openapi")]
|
||||||
|
pub use openapi::{GetOpenapi, OpenapiRouter};
|
||||||
|
|
||||||
mod resource;
|
mod resource;
|
||||||
pub use resource::{
|
pub use resource::{
|
||||||
|
@ -23,3 +25,5 @@ pub use result::{ResourceResult, Success};
|
||||||
|
|
||||||
mod routing;
|
mod routing;
|
||||||
pub use routing::{DrawResources, DrawResourceRoutes};
|
pub use routing::{DrawResources, DrawResourceRoutes};
|
||||||
|
#[cfg(feature = "openapi")]
|
||||||
|
pub use routing::WithOpenapi;
|
||||||
|
|
|
@ -18,43 +18,36 @@ use openapiv3::{MediaType, OpenAPI, Operation, PathItem, Paths, ReferenceOr, Ref
|
||||||
use serde::de::DeserializeOwned;
|
use serde::de::DeserializeOwned;
|
||||||
use std::panic::RefUnwindSafe;
|
use std::panic::RefUnwindSafe;
|
||||||
|
|
||||||
pub struct OpenapiRouter<'a, D>
|
pub struct OpenapiRouter(OpenAPI);
|
||||||
{
|
|
||||||
route : &'a mut D,
|
|
||||||
openapi : OpenAPI
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a, D> OpenapiRouter<'a, D>
|
impl OpenapiRouter
|
||||||
{
|
{
|
||||||
pub fn new<Title : ToString, Version : ToString>(route : &'a mut D, title : Title, version : Version) -> Self
|
pub fn new<Title : ToString, Version : ToString>(title : Title, version : Version) -> Self
|
||||||
{
|
{
|
||||||
Self {
|
Self(OpenAPI {
|
||||||
route,
|
openapi: "3.0.2".to_string(),
|
||||||
openapi: OpenAPI {
|
info: openapiv3::Info {
|
||||||
openapi: "3.0.2".to_string(),
|
title: title.to_string(),
|
||||||
info: openapiv3::Info {
|
description: None,
|
||||||
title: title.to_string(),
|
terms_of_service: None,
|
||||||
description: None,
|
contact: None,
|
||||||
terms_of_service: None,
|
license: None,
|
||||||
contact: None,
|
version: version.to_string()
|
||||||
license: None,
|
},
|
||||||
version: version.to_string()
|
servers: Vec::new(),
|
||||||
},
|
paths: Paths::new(),
|
||||||
servers: Vec::new(),
|
components: None,
|
||||||
paths: Paths::new(),
|
security: Vec::new(),
|
||||||
components: None,
|
tags: Vec::new(),
|
||||||
security: Vec::new(),
|
external_docs: None
|
||||||
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
|
/// 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
|
/// modify the path and add it back after the modification
|
||||||
fn remove_path(&mut self, path : &str) -> PathItem
|
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;
|
return item;
|
||||||
}
|
}
|
||||||
|
@ -74,7 +67,7 @@ impl<'a, D> OpenapiRouter<'a, D>
|
||||||
|
|
||||||
fn add_path<Path : ToString>(&mut self, path : Path, item : PathItem)
|
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
|
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 {
|
macro_rules! implOpenapiRouter {
|
||||||
($implType:ident) => {
|
($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
|
where
|
||||||
C : PipelineHandleChain<P> + Copy + Send + Sync + 'static,
|
C : PipelineHandleChain<P> + Copy + Send + Sync + 'static,
|
||||||
P : RefUnwindSafe + 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
|
where
|
||||||
C : PipelineHandleChain<P> + Copy + Send + Sync + 'static,
|
C : PipelineHandleChain<P> + Copy + Send + Sync + 'static,
|
||||||
P : RefUnwindSafe + 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
|
where
|
||||||
C : PipelineHandleChain<P> + Copy + Send + Sync + 'static,
|
C : PipelineHandleChain<P> + Copy + Send + Sync + 'static,
|
||||||
P : RefUnwindSafe + Send + Sync + 'static
|
P : RefUnwindSafe + Send + Sync + 'static
|
||||||
|
@ -156,7 +154,7 @@ macro_rules! implOpenapiRouter {
|
||||||
Handler : ResourceReadAll<Res>
|
Handler : ResourceReadAll<Res>
|
||||||
{
|
{
|
||||||
let path = &self.1;
|
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();
|
let mut content : IndexMap<String, MediaType> = IndexMap::new();
|
||||||
content[&APPLICATION_JSON.to_string()] = MediaType {
|
content[&APPLICATION_JSON.to_string()] = MediaType {
|
||||||
schema: None, // TODO
|
schema: None, // TODO
|
||||||
|
@ -187,9 +185,9 @@ macro_rules! implOpenapiRouter {
|
||||||
security: Vec::new(),
|
security: Vec::new(),
|
||||||
servers: 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)
|
fn read<Handler, ID, Res>(&mut self)
|
||||||
|
@ -198,7 +196,7 @@ macro_rules! implOpenapiRouter {
|
||||||
Res : ResourceResult,
|
Res : ResourceResult,
|
||||||
Handler : ResourceRead<ID, Res>
|
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)
|
fn create<Handler, Body, Res>(&mut self)
|
||||||
|
@ -207,7 +205,7 @@ macro_rules! implOpenapiRouter {
|
||||||
Res : ResourceResult,
|
Res : ResourceResult,
|
||||||
Handler : ResourceCreate<Body, Res>
|
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)
|
fn update_all<Handler, Body, Res>(&mut self)
|
||||||
|
@ -216,7 +214,7 @@ macro_rules! implOpenapiRouter {
|
||||||
Res : ResourceResult,
|
Res : ResourceResult,
|
||||||
Handler : ResourceUpdateAll<Body, Res>
|
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)
|
fn update<Handler, ID, Body, Res>(&mut self)
|
||||||
|
@ -226,7 +224,7 @@ macro_rules! implOpenapiRouter {
|
||||||
Res : ResourceResult,
|
Res : ResourceResult,
|
||||||
Handler : ResourceUpdate<ID, Body, Res>
|
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)
|
fn delete_all<Handler, Res>(&mut self)
|
||||||
|
@ -234,7 +232,7 @@ macro_rules! implOpenapiRouter {
|
||||||
Res : ResourceResult,
|
Res : ResourceResult,
|
||||||
Handler : ResourceDeleteAll<Res>
|
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)
|
fn delete<Handler, ID, Res>(&mut self)
|
||||||
|
@ -243,7 +241,7 @@ macro_rules! implOpenapiRouter {
|
||||||
Res : ResourceResult,
|
Res : ResourceResult,
|
||||||
Handler : ResourceDelete<ID, Res>
|
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>()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -36,7 +36,7 @@ pub trait WithOpenapi<D>
|
||||||
{
|
{
|
||||||
fn with_openapi<F, Title, Version>(&mut self, title : Title, version : Version, block : F)
|
fn with_openapi<F, Title, Version>(&mut self, title : Title, version : Version, block : F)
|
||||||
where
|
where
|
||||||
F : FnOnce(OpenapiRouter<D>),
|
F : FnOnce((&mut D, &mut OpenapiRouter)),
|
||||||
Title : ToString,
|
Title : ToString,
|
||||||
Version : ToString;
|
Version : ToString;
|
||||||
}
|
}
|
||||||
|
@ -237,12 +237,12 @@ macro_rules! implDrawResourceRoutes {
|
||||||
{
|
{
|
||||||
fn with_openapi<F, Title, Version>(&mut self, title : Title, version : Version, block : F)
|
fn with_openapi<F, Title, Version>(&mut self, title : Title, version : Version, block : F)
|
||||||
where
|
where
|
||||||
F : FnOnce(OpenapiRouter<Self>),
|
F : FnOnce((&mut Self, &mut OpenapiRouter)),
|
||||||
Title : ToString,
|
Title : ToString,
|
||||||
Version : ToString
|
Version : ToString
|
||||||
{
|
{
|
||||||
let router : OpenapiRouter<Self> = OpenapiRouter::new(self, title, version);
|
let mut router = OpenapiRouter::new(title, version);
|
||||||
block(router);
|
block((self, &mut router));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue