mirror of
https://gitlab.com/msrd0/gotham-restful.git
synced 2025-02-23 04:52:28 +00:00
first valid openapi spec generated
This commit is contained in:
parent
681482ece3
commit
d9b4b22af3
4 changed files with 130 additions and 20 deletions
|
@ -1,4 +1,11 @@
|
|||
#[cfg(feature = "openapi")]
|
||||
pub mod openapi
|
||||
{
|
||||
pub use indexmap::IndexMap;
|
||||
pub use openapiv3::{ObjectType, ReferenceOr, Schema, SchemaData, SchemaKind, Type};
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "openapi"))]
|
||||
#[macro_export]
|
||||
macro_rules! rest_struct {
|
||||
($struct_name:ident { $($field_id:ident : $field_ty:ty),* }) => {
|
||||
|
@ -10,6 +17,52 @@ macro_rules! rest_struct {
|
|||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "openapi")]
|
||||
#[macro_export]
|
||||
macro_rules! rest_struct {
|
||||
($struct_name:ident { $($field_id:ident : $field_ty:ty),* }) => {
|
||||
#[derive(serde::Deserialize, serde::Serialize)]
|
||||
struct $struct_name
|
||||
{
|
||||
$($field_id : $field_ty),*
|
||||
}
|
||||
|
||||
impl ::gotham_restful::OpenapiType for $struct_name
|
||||
{
|
||||
fn schema_name() -> Option<String>
|
||||
{
|
||||
Some(stringify!($struct_name).to_string())
|
||||
}
|
||||
|
||||
fn to_schema() -> ::gotham_restful::helper::openapi::SchemaKind
|
||||
{
|
||||
use ::gotham_restful::helper::openapi::*;
|
||||
|
||||
let mut properties : IndexMap<String, ReferenceOr<Box<Schema>>> = IndexMap::new();
|
||||
let mut required : Vec<String> = Vec::new();
|
||||
|
||||
$(
|
||||
properties.insert(
|
||||
stringify!($field_id).to_string(),
|
||||
ReferenceOr::Item(Box::new(Schema {
|
||||
schema_data: SchemaData::default(),
|
||||
schema_kind: <$field_ty>::to_schema()
|
||||
}))
|
||||
);
|
||||
)*
|
||||
|
||||
SchemaKind::Type(Type::Object(ObjectType {
|
||||
properties,
|
||||
required,
|
||||
additional_properties: None,
|
||||
min_properties: None,
|
||||
max_properties: None
|
||||
}))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! rest_resource {
|
||||
($res_name:ident, $route:ident => $setup:block) => {
|
||||
|
|
|
@ -15,7 +15,8 @@ use indexmap::IndexMap;
|
|||
use log::error;
|
||||
use mime::{APPLICATION_JSON, TEXT_PLAIN};
|
||||
use openapiv3::{
|
||||
MediaType, OpenAPI, Operation, PathItem, Paths, ReferenceOr, ReferenceOr::Item, Response, Responses, Server, StatusCode
|
||||
Components, MediaType, OpenAPI, Operation, PathItem, Paths, ReferenceOr, ReferenceOr::Item, ReferenceOr::Reference,
|
||||
Response, Responses, Schema, SchemaData, Server, StatusCode
|
||||
};
|
||||
use serde::de::DeserializeOwned;
|
||||
use std::panic::RefUnwindSafe;
|
||||
|
@ -57,24 +58,27 @@ impl OpenapiRouter
|
|||
{
|
||||
return item;
|
||||
}
|
||||
return PathItem {
|
||||
get: None,
|
||||
put: None,
|
||||
post: None,
|
||||
delete: None,
|
||||
options: None,
|
||||
head: None,
|
||||
patch: None,
|
||||
trace: None,
|
||||
servers: Vec::new(),
|
||||
parameters: Vec::new()
|
||||
};
|
||||
return PathItem::default()
|
||||
}
|
||||
|
||||
fn add_path<Path : ToString>(&mut self, path : Path, item : PathItem)
|
||||
{
|
||||
self.0.paths.insert(path.to_string(), Item(item));
|
||||
}
|
||||
|
||||
fn add_schema<Name : ToString>(&mut self, name : Name, item : Schema)
|
||||
{
|
||||
match &mut self.0.components {
|
||||
Some(comp) => {
|
||||
comp.schemas.insert(name.to_string(), Item(item));
|
||||
},
|
||||
None => {
|
||||
let mut comp = Components::default();
|
||||
comp.schemas.insert(name.to_string(), Item(item));
|
||||
self.0.components = Some(comp);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
|
@ -159,11 +163,21 @@ macro_rules! implOpenapiRouter {
|
|||
Res : ResourceResult,
|
||||
Handler : ResourceReadAll<Res>
|
||||
{
|
||||
let path = &self.1;
|
||||
let mut item = (self.0).1.remove_path(path);
|
||||
let schema = Res::schema_name().unwrap_or_else(|| {
|
||||
format!("Resource_{}_ReadAllResult", self.1)
|
||||
});
|
||||
(self.0).1.add_schema(&schema, Schema {
|
||||
schema_data: SchemaData::default(),
|
||||
schema_kind: Res::to_schema()
|
||||
});
|
||||
|
||||
let path = format!("/{}", &self.1);
|
||||
let mut item = (self.0).1.remove_path(&path);
|
||||
let mut content : IndexMap<String, MediaType> = IndexMap::new();
|
||||
content.insert(APPLICATION_JSON.to_string(), MediaType {
|
||||
schema: None, // TODO
|
||||
schema: Some(Reference {
|
||||
reference: format!("#/components/schemas/{}", schema)
|
||||
}),
|
||||
example: None,
|
||||
examples: IndexMap::new(),
|
||||
encoding: IndexMap::new()
|
||||
|
|
|
@ -1,12 +1,17 @@
|
|||
use indexmap::IndexMap;
|
||||
use openapiv3::{
|
||||
IntegerType, NumberType, ObjectType, SchemaKind, StringType, Type
|
||||
ArrayType, IntegerType, NumberType, ObjectType, ReferenceOr::Item, Schema, SchemaData, SchemaKind, StringType, Type
|
||||
};
|
||||
use serde::Serialize;
|
||||
|
||||
|
||||
pub trait OpenapiType : Serialize
|
||||
{
|
||||
fn schema_name() -> Option<String>
|
||||
{
|
||||
None
|
||||
}
|
||||
|
||||
fn to_schema() -> SchemaKind;
|
||||
}
|
||||
|
||||
|
@ -67,3 +72,24 @@ macro_rules! str_types {
|
|||
}
|
||||
|
||||
str_types!(String, &str);
|
||||
|
||||
impl<T : OpenapiType> OpenapiType for Vec<T>
|
||||
{
|
||||
fn schema_name() -> Option<String>
|
||||
{
|
||||
T::schema_name().map(|name| format!("{}Array", name))
|
||||
}
|
||||
|
||||
fn to_schema() -> SchemaKind
|
||||
{
|
||||
SchemaKind::Type(Type::Array(ArrayType {
|
||||
items: Item(Box::new(Schema {
|
||||
schema_data: SchemaData::default(),
|
||||
schema_kind: T::to_schema()
|
||||
})),
|
||||
min_items: None,
|
||||
max_items: None,
|
||||
unique_items: false
|
||||
}))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,6 +9,9 @@ pub trait ResourceResult
|
|||
{
|
||||
fn to_json(&self) -> Result<(StatusCode, String), SerdeJsonError>;
|
||||
|
||||
#[cfg(feature = "openapi")]
|
||||
fn schema_name() -> Option<String>;
|
||||
|
||||
#[cfg(feature = "openapi")]
|
||||
fn to_schema() -> SchemaKind;
|
||||
}
|
||||
|
@ -45,6 +48,13 @@ impl<R : ResourceType, E : Error> ResourceResult for Result<R, E>
|
|||
})
|
||||
}
|
||||
|
||||
#[cfg(feature = "openapi")]
|
||||
fn schema_name() -> Option<String>
|
||||
{
|
||||
R::schema_name()
|
||||
}
|
||||
|
||||
#[cfg(feature = "openapi")]
|
||||
fn to_schema() -> SchemaKind
|
||||
{
|
||||
R::to_schema()
|
||||
|
@ -69,6 +79,13 @@ impl<T : ResourceType> ResourceResult for Success<T>
|
|||
Ok((StatusCode::OK, serde_json::to_string(&self.0)?))
|
||||
}
|
||||
|
||||
#[cfg(feature = "openapi")]
|
||||
fn schema_name() -> Option<String>
|
||||
{
|
||||
T::schema_name()
|
||||
}
|
||||
|
||||
#[cfg(feature = "openapi")]
|
||||
fn to_schema() -> SchemaKind
|
||||
{
|
||||
T::to_schema()
|
||||
|
|
Loading…
Add table
Reference in a new issue