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

better type support

This commit is contained in:
Dominic 2019-10-20 18:23:36 +02:00
parent 6e7dd2c610
commit cff5f55d64
Signed by: msrd0
GPG key ID: DCC8C247452E98F9
3 changed files with 80 additions and 15 deletions

View file

@ -29,6 +29,7 @@ mime = "0.3"
openapiv3 = { version = "0.3", optional = true } openapiv3 = { version = "0.3", optional = true }
serde = { version = "1", features = ["derive"] } serde = { version = "1", features = ["derive"] }
serde_json = "1" serde_json = "1"
uuid = { version = ">= 0.1, < 0.9", optional = true }
[dev-dependencies] [dev-dependencies]
thiserror = "1" thiserror = "1"

View file

@ -90,6 +90,7 @@ If you encounter any issues that aren't yet reported, please report them
[here](https://gitlab.com/msrd0/gotham-restful/issues/new). [here](https://gitlab.com/msrd0/gotham-restful/issues/new).
- Enabling the `openapi` feature might break code ([#4](https://gitlab.com/msrd0/gotham-restful/issues/4)) - Enabling the `openapi` feature might break code ([#4](https://gitlab.com/msrd0/gotham-restful/issues/4))
- For `chrono`'s `DateTime` types, the format is `date-time` instead of `datetime` ([openapiv3#14](https://github.com/glademiller/openapiv3/pull/14))
# License # License

View file

@ -5,10 +5,10 @@ use chrono::{
use indexmap::IndexMap; use indexmap::IndexMap;
use openapiv3::{ use openapiv3::{
ArrayType, IntegerType, NumberType, ObjectType, ReferenceOr::Item, ReferenceOr::Reference, Schema, ArrayType, IntegerType, NumberType, ObjectType, ReferenceOr::Item, ReferenceOr::Reference, Schema,
SchemaData, SchemaKind, StringType, Type SchemaData, SchemaKind, StringType, Type, VariantOrUnknownOrEmpty
}; };
#[cfg(feature = "chrono")] #[cfg(feature = "uuid")]
use openapiv3::{StringFormat, VariantOrUnknownOrEmpty}; use uuid::Uuid;
/** /**
This struct needs to be available for every type that can be part of an OpenAPI Spec. It is This struct needs to be available for every type that can be part of an OpenAPI Spec. It is
@ -52,15 +52,8 @@ impl OpenapiSchema
Schema { Schema {
schema_data: SchemaData { schema_data: SchemaData {
nullable: self.nullable, nullable: self.nullable,
read_only: false,
write_only: false,
deprecated: false,
external_docs: None,
example: None,
title: self.name, title: self.name,
description: None, ..Default::default()
discriminator: None,
default: None
}, },
schema_kind: self.schema schema_kind: self.schema
} }
@ -80,6 +73,8 @@ struct MyResponse {
message: String message: String
} }
``` ```
[`OpenapiSchema`]: struct.OpenapiSchema.html
*/ */
pub trait OpenapiType pub trait OpenapiType
{ {
@ -111,10 +106,61 @@ macro_rules! int_types {
OpenapiSchema::new(SchemaKind::Type(Type::Integer(IntegerType::default()))) OpenapiSchema::new(SchemaKind::Type(Type::Integer(IntegerType::default())))
} }
} }
)*} )*};
(unsigned $($int_ty:ty),*) => {$(
impl OpenapiType for $int_ty
{
fn schema() -> OpenapiSchema
{
OpenapiSchema::new(SchemaKind::Type(Type::Integer(IntegerType {
minimum: Some(0),
..Default::default()
})))
}
}
)*};
(bits = $bits:expr, $($int_ty:ty),*) => {$(
impl OpenapiType for $int_ty
{
fn schema() -> OpenapiSchema
{
OpenapiSchema::new(SchemaKind::Type(Type::Integer(IntegerType {
format: VariantOrUnknownOrEmpty::Unknown(format!("int{}", $bits)),
..Default::default()
})))
}
}
)*};
(unsigned bits = $bits:expr, $($int_ty:ty),*) => {$(
impl OpenapiType for $int_ty
{
fn schema() -> OpenapiSchema
{
OpenapiSchema::new(SchemaKind::Type(Type::Integer(IntegerType {
format: VariantOrUnknownOrEmpty::Unknown(format!("int{}", $bits)),
minimum: Some(0),
..Default::default()
})))
}
}
)*};
} }
int_types!(u8, u16, u32, u64, u128, usize, i8, i16, i32, i64, i128); int_types!(isize);
int_types!(unsigned usize);
int_types!(bits = 8, i8);
int_types!(unsigned bits = 8, u8);
int_types!(bits = 16, i16);
int_types!(unsigned bits = 16, u16);
int_types!(bits = 32, i32);
int_types!(unsigned bits = 32, u32);
int_types!(bits = 64, i64);
int_types!(unsigned bits = 64, u64);
int_types!(bits = 128, i128);
int_types!(unsigned bits = 128, u128);
macro_rules! num_types { macro_rules! num_types {
($($num_ty:ty),*) => {$( ($($num_ty:ty),*) => {$(
@ -146,10 +192,24 @@ macro_rules! str_types {
{ {
fn schema() -> OpenapiSchema fn schema() -> OpenapiSchema
{ {
use openapiv3::StringFormat;
OpenapiSchema::new(SchemaKind::Type(Type::String(StringType { OpenapiSchema::new(SchemaKind::Type(Type::String(StringType {
format: VariantOrUnknownOrEmpty::Item(StringFormat::$format), format: VariantOrUnknownOrEmpty::Item(StringFormat::$format),
pattern: None, ..Default::default()
enumeration: Vec::new() })))
}
}
)*};
(format_str = $format:expr, $($str_ty:ty),*) => {$(
impl OpenapiType for $str_ty
{
fn schema() -> OpenapiSchema
{
OpenapiSchema::new(SchemaKind::Type(Type::String(StringType {
format: VariantOrUnknownOrEmpty::Unknown($format.to_string()),
..Default::default()
}))) })))
} }
} }
@ -217,3 +277,6 @@ impl<T : OpenapiType> OpenapiType for Vec<T>
str_types!(format = Date, Date<FixedOffset>, Date<Local>, Date<Utc>, NaiveDate); str_types!(format = Date, Date<FixedOffset>, Date<Local>, Date<Utc>, NaiveDate);
#[cfg(feature = "chrono")] #[cfg(feature = "chrono")]
str_types!(format = DateTime, DateTime<FixedOffset>, DateTime<Local>, DateTime<Utc>, NaiveDateTime); str_types!(format = DateTime, DateTime<FixedOffset>, DateTime<Local>, DateTime<Utc>, NaiveDateTime);
#[cfg(feature = "uuid")]
str_types!(format_str = "uuid", Uuid);