1
0
Fork 0
mirror of https://gitlab.com/msrd0/gotham-restful.git synced 2025-02-23 04:52:28 +00:00

try to further simply trait stuff, however, rust doesn't like that: https://github.com/rust-lang/rust/issues/48869

This commit is contained in:
Dominic 2020-03-30 20:39:01 +02:00
parent 7486c23727
commit 91f7b09fbf
Signed by: msrd0
GPG key ID: DCC8C247452E98F9
3 changed files with 266 additions and 178 deletions

View file

@ -151,7 +151,7 @@ pub use auth::{
mod openapi; mod openapi;
#[cfg(feature = "openapi")] #[cfg(feature = "openapi")]
pub use openapi::{ pub use openapi::{
router::{GetOpenapi, OpenapiRouter}, router::GetOpenapi,
types::{OpenapiSchema, OpenapiType} types::{OpenapiSchema, OpenapiType}
}; };

View file

@ -12,8 +12,14 @@ use gotham::{
extractor::QueryStringExtractor, extractor::QueryStringExtractor,
handler::{Handler, HandlerFuture, NewHandler}, handler::{Handler, HandlerFuture, NewHandler},
helpers::http::response::create_response, helpers::http::response::create_response,
pipeline::chain::PipelineHandleChain, pipeline::{
router::builder::*, chain::PipelineHandleChain,
set::PipelineSet
},
router::{
builder::*,
tree::node::Node
},
state::State state::State
}; };
use hyper::Body; use hyper::Body;
@ -28,15 +34,10 @@ use openapiv3::{
use serde::de::DeserializeOwned; use serde::de::DeserializeOwned;
use std::panic::RefUnwindSafe; use std::panic::RefUnwindSafe;
/** /// A helper struct for `OpenapiRouter` to build the OpenAPI specification.
This type is required to build routes while adding them to the generated OpenAPI Spec at the pub struct OpenapiBuilder(OpenAPI);
same time. There is no need to use this type directly. See [`WithOpenapi`] on how to do this.
[`WithOpenapi`]: trait.WithOpenapi.html impl OpenapiBuilder
*/
pub struct OpenapiRouter(OpenAPI);
impl OpenapiRouter
{ {
pub fn new<Title : ToString, Version : ToString, Url : ToString>(title : Title, version : Version, server_url : Url) -> Self pub fn new<Title : ToString, Version : ToString, Url : ToString>(title : Title, version : Version, server_url : Url) -> Self
{ {
@ -129,7 +130,7 @@ struct OpenapiHandler(OpenAPI);
impl OpenapiHandler impl OpenapiHandler
{ {
fn new(openapi : &OpenapiRouter) -> Self fn new(openapi : &OpenapiBuilder) -> Self
{ {
Self(openapi.0.clone()) Self(openapi.0.clone())
} }
@ -365,32 +366,125 @@ fn new_operation(
} }
} }
macro_rules! implOpenapiRouter { struct OpenapiRouteBuilder<'a, C, P>
($implType:ident) => { where
C : PipelineHandleChain<P> + Copy + Send + Sync + 'static,
P : Send + Sync + 'static
{
node_builder : &'a mut Node,
pipeline_chain : C,
pipelines : PipelineSet<P>
}
impl<'a, C, P> GetOpenapi for (&mut $implType<'a, C, P>, &mut OpenapiRouter) impl<'a, C, P> OpenapiRouteBuilder<'a, C, P>
where
C : PipelineHandleChain<P> + Copy + Send + Sync + 'static,
P : RefUnwindSafe + Send + Sync + 'static
{
fn new<D>(router : &'a mut D) -> Self
where
D : DrawRoutes<C, P> + 'a
{
let (node_builder, pipeline_chain, pipelines) = router.component_refs();
Self {
node_builder,
pipeline_chain: *pipeline_chain,
pipelines: pipelines.clone()
}
}
}
impl<'a, C, P> DrawRoutes<C, P> for OpenapiRouteBuilder<'a, C, P>
where
C : PipelineHandleChain<P> + Copy + Send + Sync + 'static,
P : RefUnwindSafe + Send + Sync + 'static
{
fn component_refs(&mut self) -> (&mut Node, &mut C, &PipelineSet<P>)
{
(&mut self.node_builder, &mut self.pipeline_chain, &self.pipelines)
}
}
/**
This type is required to build routes while adding them to the generated OpenAPI Spec at the
same time. There is no need to use this type directly. See [`WithOpenapi`] on how to do this.
[`WithOpenapi`]: trait.WithOpenapi.html
*/
pub struct OpenapiRouter<'a, C, P>
where
C : PipelineHandleChain<P> + Copy + Send + Sync + 'static,
P : Send + Sync + 'static
{
builder : OpenapiRouteBuilder<'a, C, P>,
openapi : OpenapiBuilder
}
impl<'a, C, P> OpenapiRouter<'a, C, P>
where
C : PipelineHandleChain<P> + Copy + Send + Sync + 'static,
P : RefUnwindSafe + Send + Sync + 'static
{
pub fn new<D>(router : &'a mut D, openapi : OpenapiBuilder) -> Self
where
D : DrawRoutes<C, P>
{
Self {
builder: OpenapiRouteBuilder::new(router),
openapi
}
}
}
impl<'a, C, P> GetOpenapi for OpenapiRouter<'a, C, P>
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
{ {
fn get_openapi(&mut self, path : &str) fn get_openapi(&mut self, path : &str)
{ {
self.0.get(path).to_new_handler(OpenapiHandler::new(&self.1)); self.builder.get(path).to_new_handler(OpenapiHandler::new(&self.openapi));
} }
} }
impl<'a, C, P> DrawResources for (&mut $implType<'a, C, P>, &mut OpenapiRouter) impl<'a, C, P> DrawResources<C, P> for OpenapiRouter<'a, C, P>
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
{ {
fn resource<R : Resource, T : ToString>(&mut self, path : T) fn resource<'b, R : Resource>(&'b mut self, path : &'b str)
{ {
R::setup((self, path.to_string())); R::setup(OpenapiResourceSetup::new(self, path));
} }
} }
impl<'a, C, P> DrawResourceRoutes for (&mut (&mut $implType<'a, C, P>, &mut OpenapiRouter), String) struct OpenapiResourceSetup<'a, C, P>
where
C : PipelineHandleChain<P> + Copy + Send + Sync + 'static,
P : Send + Sync + 'static
{
builder : OpenapiRouteBuilder<'a, C, P>,
openapi : &'a mut OpenapiBuilder,
path : &'a str
}
impl<'a, C, P> OpenapiResourceSetup<'a, C, P>
where
C : PipelineHandleChain<P> + Copy + Send + Sync + 'static,
P : Send + Sync + 'static
{
fn new(router : &'a mut OpenapiRouter<'a, C, P>, path : &'a str) -> Self
{
Self {
builder: &mut router.builder,
openapi: &mut router.openapi,
path
}
}
}
/*
impl<'a, C, P> DrawResourceRoutes for OpenapiResourceSetup<'a, C, P>
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
@ -526,13 +620,6 @@ macro_rules! implOpenapiRouter {
} }
} }
}
}
implOpenapiRouter!(RouterBuilder);
implOpenapiRouter!(ScopeBuilder);
#[cfg(test)] #[cfg(test)]
mod test mod test
{ {
@ -603,3 +690,4 @@ mod test
assert_eq!(json, r#"{"schema":{"type":"string","format":"binary"}}"#); assert_eq!(json, r#"{"schema":{"type":"string","format":"binary"}}"#);
} }
} }
*/

View file

@ -6,7 +6,7 @@ use crate::{
StatusCode StatusCode
}; };
#[cfg(feature = "openapi")] #[cfg(feature = "openapi")]
use crate::OpenapiRouter; use crate::openapi::router::{OpenapiBuilder, OpenapiRouter};
use futures::{ use futures::{
future::{Future, err, ok}, future::{Future, err, ok},
@ -60,7 +60,7 @@ where
{ {
fn with_openapi<F, Title, Version, Url>(&mut self, title : Title, version : Version, server_url : Url, block : F) fn with_openapi<F, Title, Version, Url>(&mut self, title : Title, version : Version, server_url : Url, block : F)
where where
F : FnOnce((&mut D, &mut OpenapiRouter)), F : FnOnce(OpenapiRouter<C, P>),
Title : ToString, Title : ToString,
Version : ToString, Version : ToString,
Url : ToString; Url : ToString;
@ -355,13 +355,13 @@ where
{ {
fn with_openapi<F, Title, Version, Url>(&mut self, title : Title, version : Version, server_url : Url, block : F) fn with_openapi<F, Title, Version, Url>(&mut self, title : Title, version : Version, server_url : Url, block : F)
where where
F : FnOnce((&mut Self, &mut OpenapiRouter)), F : FnOnce(OpenapiRouter<C, P>),
Title : ToString, Title : ToString,
Version : ToString, Version : ToString,
Url : ToString Url : ToString
{ {
let mut router = OpenapiRouter::new(title, version, server_url); let router = OpenapiRouter::new(self, OpenapiBuilder::new(title, version, server_url));
block((self, &mut router)); block(router);
} }
} }