mirror of
https://gitlab.com/msrd0/gotham-restful.git
synced 2025-04-19 06:24:45 +00:00
redo and test openapi type implementations
This commit is contained in:
parent
2a35e044db
commit
eecd192458
4 changed files with 413 additions and 291 deletions
|
@ -17,6 +17,10 @@ openapi_type_derive = "0.1.0-dev"
|
||||||
openapiv3 = "=0.3.2"
|
openapiv3 = "=0.3.2"
|
||||||
serde_json = "1.0"
|
serde_json = "1.0"
|
||||||
|
|
||||||
|
# optional dependencies / features
|
||||||
|
chrono = { version = "0.4.19", optional = true }
|
||||||
|
uuid = { version = "0.8.2" , optional = true }
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
paste = "1.0"
|
paste = "1.0"
|
||||||
serde = "1.0"
|
serde = "1.0"
|
||||||
|
|
|
@ -1,203 +1,120 @@
|
||||||
use crate::{OpenapiSchema, OpenapiType};
|
use crate::{OpenapiSchema, OpenapiType};
|
||||||
use indexmap::IndexMap;
|
#[cfg(feature = "chrono")]
|
||||||
|
use chrono::{offset::TimeZone, Date, DateTime, NaiveDate, NaiveDateTime};
|
||||||
|
use indexmap::{IndexMap, IndexSet};
|
||||||
use openapiv3::{
|
use openapiv3::{
|
||||||
AdditionalProperties, ArrayType, IntegerType, NumberFormat, NumberType, ObjectType, ReferenceOr, SchemaKind, StringType,
|
AdditionalProperties, ArrayType, IntegerType, NumberFormat, NumberType, ObjectType, ReferenceOr, SchemaKind,
|
||||||
Type, VariantOrUnknownOrEmpty
|
StringFormat, StringType, Type, VariantOrUnknownOrEmpty
|
||||||
};
|
};
|
||||||
|
use serde_json::Value;
|
||||||
use std::{
|
use std::{
|
||||||
collections::{BTreeSet, HashMap, HashSet},
|
collections::{BTreeMap, BTreeSet, HashMap, HashSet},
|
||||||
hash::BuildHasher,
|
hash::BuildHasher,
|
||||||
num::{NonZeroU128, NonZeroU16, NonZeroU32, NonZeroU64, NonZeroU8, NonZeroUsize}
|
num::{NonZeroU128, NonZeroU16, NonZeroU32, NonZeroU64, NonZeroU8, NonZeroUsize}
|
||||||
};
|
};
|
||||||
|
#[cfg(feature = "uuid")]
|
||||||
|
use uuid::Uuid;
|
||||||
|
|
||||||
impl OpenapiType for () {
|
macro_rules! impl_openapi_type {
|
||||||
|
($($ty:ident $(<$($generic:ident : $bound:path),+>)*),* => $schema:expr) => {
|
||||||
|
$(
|
||||||
|
impl $(<$($generic : $bound),+>)* OpenapiType for $ty $(<$($generic),+>)* {
|
||||||
fn schema() -> OpenapiSchema {
|
fn schema() -> OpenapiSchema {
|
||||||
|
$schema
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)*
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
type Unit = ();
|
||||||
|
impl_openapi_type!(Unit => {
|
||||||
OpenapiSchema::new(SchemaKind::Type(Type::Object(ObjectType {
|
OpenapiSchema::new(SchemaKind::Type(Type::Object(ObjectType {
|
||||||
additional_properties: Some(AdditionalProperties::Any(false)),
|
additional_properties: Some(AdditionalProperties::Any(false)),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
})))
|
})))
|
||||||
|
});
|
||||||
|
|
||||||
|
impl_openapi_type!(Value => {
|
||||||
|
OpenapiSchema {
|
||||||
|
nullable: true,
|
||||||
|
name: None,
|
||||||
|
schema: SchemaKind::Any(Default::default()),
|
||||||
|
dependencies: Default::default()
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
impl_openapi_type!(bool => OpenapiSchema::new(SchemaKind::Type(Type::Boolean {})));
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn int_schema(minimum: Option<i64>, bits: Option<i64>) -> OpenapiSchema {
|
||||||
|
OpenapiSchema::new(SchemaKind::Type(Type::Integer(IntegerType {
|
||||||
|
minimum,
|
||||||
|
format: bits
|
||||||
|
.map(|bits| VariantOrUnknownOrEmpty::Unknown(format!("int{}", bits)))
|
||||||
|
.unwrap_or(VariantOrUnknownOrEmpty::Empty),
|
||||||
|
..Default::default()
|
||||||
|
})))
|
||||||
}
|
}
|
||||||
|
|
||||||
impl OpenapiType for bool {
|
impl_openapi_type!(isize => int_schema(None, None));
|
||||||
fn schema() -> OpenapiSchema {
|
impl_openapi_type!(i8 => int_schema(None, Some(8)));
|
||||||
OpenapiSchema::new(SchemaKind::Type(Type::Boolean {}))
|
impl_openapi_type!(i16 => int_schema(None, Some(16)));
|
||||||
}
|
impl_openapi_type!(i32 => int_schema(None, Some(32)));
|
||||||
}
|
impl_openapi_type!(i64 => int_schema(None, Some(64)));
|
||||||
|
impl_openapi_type!(i128 => int_schema(None, Some(128)));
|
||||||
|
|
||||||
macro_rules! int_types {
|
impl_openapi_type!(usize => int_schema(Some(0), None));
|
||||||
($($int_ty:ty),*) => {$(
|
impl_openapi_type!(u8 => int_schema(Some(0), Some(8)));
|
||||||
impl OpenapiType for $int_ty
|
impl_openapi_type!(u16 => int_schema(Some(0), Some(16)));
|
||||||
{
|
impl_openapi_type!(u32 => int_schema(Some(0), Some(32)));
|
||||||
fn schema() -> OpenapiSchema
|
impl_openapi_type!(u64 => int_schema(Some(0), Some(64)));
|
||||||
{
|
impl_openapi_type!(u128 => int_schema(Some(0), Some(128)));
|
||||||
OpenapiSchema::new(SchemaKind::Type(Type::Integer(IntegerType::default())))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)*};
|
|
||||||
|
|
||||||
(unsigned $($int_ty:ty),*) => {$(
|
impl_openapi_type!(NonZeroUsize => int_schema(Some(1), None));
|
||||||
impl OpenapiType for $int_ty
|
impl_openapi_type!(NonZeroU8 => int_schema(Some(1), Some(8)));
|
||||||
{
|
impl_openapi_type!(NonZeroU16 => int_schema(Some(1), Some(16)));
|
||||||
fn schema() -> OpenapiSchema
|
impl_openapi_type!(NonZeroU32 => int_schema(Some(1), Some(32)));
|
||||||
{
|
impl_openapi_type!(NonZeroU64 => int_schema(Some(1), Some(64)));
|
||||||
OpenapiSchema::new(SchemaKind::Type(Type::Integer(IntegerType {
|
impl_openapi_type!(NonZeroU128 => int_schema(Some(1), Some(128)));
|
||||||
minimum: Some(0),
|
|
||||||
..Default::default()
|
|
||||||
})))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)*};
|
|
||||||
|
|
||||||
(gtzero $($int_ty:ty),*) => {$(
|
#[inline]
|
||||||
impl OpenapiType for $int_ty
|
fn float_schema(format: NumberFormat) -> OpenapiSchema {
|
||||||
{
|
|
||||||
fn schema() -> OpenapiSchema
|
|
||||||
{
|
|
||||||
OpenapiSchema::new(SchemaKind::Type(Type::Integer(IntegerType {
|
|
||||||
minimum: Some(1),
|
|
||||||
..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()
|
|
||||||
})))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)*};
|
|
||||||
|
|
||||||
(gtzero 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(1),
|
|
||||||
..Default::default()
|
|
||||||
})))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)*};
|
|
||||||
}
|
|
||||||
|
|
||||||
int_types!(isize);
|
|
||||||
int_types!(unsigned usize);
|
|
||||||
int_types!(gtzero NonZeroUsize);
|
|
||||||
int_types!(bits = 8, i8);
|
|
||||||
int_types!(unsigned bits = 8, u8);
|
|
||||||
int_types!(gtzero bits = 8, NonZeroU8);
|
|
||||||
int_types!(bits = 16, i16);
|
|
||||||
int_types!(unsigned bits = 16, u16);
|
|
||||||
int_types!(gtzero bits = 16, NonZeroU16);
|
|
||||||
int_types!(bits = 32, i32);
|
|
||||||
int_types!(unsigned bits = 32, u32);
|
|
||||||
int_types!(gtzero bits = 32, NonZeroU32);
|
|
||||||
int_types!(bits = 64, i64);
|
|
||||||
int_types!(unsigned bits = 64, u64);
|
|
||||||
int_types!(gtzero bits = 64, NonZeroU64);
|
|
||||||
int_types!(bits = 128, i128);
|
|
||||||
int_types!(unsigned bits = 128, u128);
|
|
||||||
int_types!(gtzero bits = 128, NonZeroU128);
|
|
||||||
|
|
||||||
macro_rules! num_types {
|
|
||||||
($($num_ty:ty = $num_fmt:ident),*) => {$(
|
|
||||||
impl OpenapiType for $num_ty
|
|
||||||
{
|
|
||||||
fn schema() -> OpenapiSchema
|
|
||||||
{
|
|
||||||
OpenapiSchema::new(SchemaKind::Type(Type::Number(NumberType {
|
OpenapiSchema::new(SchemaKind::Type(Type::Number(NumberType {
|
||||||
format: VariantOrUnknownOrEmpty::Item(NumberFormat::$num_fmt),
|
format: VariantOrUnknownOrEmpty::Item(format),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
})))
|
})))
|
||||||
}
|
|
||||||
}
|
|
||||||
)*}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
num_types!(f32 = Float, f64 = Double);
|
impl_openapi_type!(f32 => float_schema(NumberFormat::Float));
|
||||||
|
impl_openapi_type!(f64 => float_schema(NumberFormat::Double));
|
||||||
macro_rules! str_types {
|
|
||||||
($($str_ty:ty),*) => {$(
|
|
||||||
impl OpenapiType for $str_ty
|
|
||||||
{
|
|
||||||
fn schema() -> OpenapiSchema
|
|
||||||
{
|
|
||||||
OpenapiSchema::new(SchemaKind::Type(Type::String(StringType::default())))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)*};
|
|
||||||
|
|
||||||
(format = $format:ident, $($str_ty:ty),*) => {$(
|
|
||||||
impl OpenapiType for $str_ty
|
|
||||||
{
|
|
||||||
fn schema() -> OpenapiSchema
|
|
||||||
{
|
|
||||||
use openapiv3::StringFormat;
|
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn str_schema(format: VariantOrUnknownOrEmpty<StringFormat>) -> OpenapiSchema {
|
||||||
OpenapiSchema::new(SchemaKind::Type(Type::String(StringType {
|
OpenapiSchema::new(SchemaKind::Type(Type::String(StringType {
|
||||||
format: VariantOrUnknownOrEmpty::Item(StringFormat::$format),
|
format,
|
||||||
..Default::default()
|
..Default::default()
|
||||||
})))
|
})))
|
||||||
}
|
|
||||||
}
|
|
||||||
)*};
|
|
||||||
|
|
||||||
(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()
|
|
||||||
})))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)*};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
str_types!(String, &str);
|
impl_openapi_type!(String => str_schema(VariantOrUnknownOrEmpty::Empty));
|
||||||
|
|
||||||
#[cfg(feature = "chrono")]
|
#[cfg(feature = "chrono")]
|
||||||
str_types!(format = Date, Date<FixedOffset>, Date<Local>, Date<Utc>, NaiveDate);
|
impl_openapi_type!(Date<T: TimeZone>, NaiveDate => {
|
||||||
|
str_schema(VariantOrUnknownOrEmpty::Item(StringFormat::Date))
|
||||||
|
});
|
||||||
|
|
||||||
#[cfg(feature = "chrono")]
|
#[cfg(feature = "chrono")]
|
||||||
str_types!(
|
impl_openapi_type!(DateTime<T: TimeZone>, NaiveDateTime => {
|
||||||
format = DateTime,
|
str_schema(VariantOrUnknownOrEmpty::Item(StringFormat::DateTime))
|
||||||
DateTime<FixedOffset>,
|
});
|
||||||
DateTime<Local>,
|
|
||||||
DateTime<Utc>,
|
|
||||||
NaiveDateTime
|
|
||||||
);
|
|
||||||
|
|
||||||
#[cfg(feature = "uuid")]
|
#[cfg(feature = "uuid")]
|
||||||
str_types!(format_str = "uuid", Uuid);
|
impl_openapi_type!(Uuid => {
|
||||||
|
str_schema(VariantOrUnknownOrEmpty::Unknown("uuid".to_owned()))
|
||||||
|
});
|
||||||
|
|
||||||
impl<T: OpenapiType> OpenapiType for Option<T> {
|
impl_openapi_type!(Option<T: OpenapiType> => {
|
||||||
fn schema() -> OpenapiSchema {
|
|
||||||
let schema = T::schema();
|
let schema = T::schema();
|
||||||
let mut dependencies = schema.dependencies.clone();
|
let mut dependencies = schema.dependencies.clone();
|
||||||
let schema = match schema.name.clone() {
|
let schema = match schema.name.clone() {
|
||||||
|
@ -217,11 +134,10 @@ impl<T: OpenapiType> OpenapiType for Option<T> {
|
||||||
schema,
|
schema,
|
||||||
dependencies
|
dependencies
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
}
|
|
||||||
|
|
||||||
impl<T: OpenapiType> OpenapiType for Vec<T> {
|
#[inline]
|
||||||
fn schema() -> OpenapiSchema {
|
fn array_schema<T: OpenapiType>(unique_items: bool) -> OpenapiSchema {
|
||||||
let schema = T::schema();
|
let schema = T::schema();
|
||||||
let mut dependencies = schema.dependencies.clone();
|
let mut dependencies = schema.dependencies.clone();
|
||||||
|
|
||||||
|
@ -243,27 +159,19 @@ impl<T: OpenapiType> OpenapiType for Vec<T> {
|
||||||
items,
|
items,
|
||||||
min_items: None,
|
min_items: None,
|
||||||
max_items: None,
|
max_items: None,
|
||||||
unique_items: false
|
unique_items
|
||||||
})),
|
})),
|
||||||
dependencies
|
dependencies
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: OpenapiType> OpenapiType for BTreeSet<T> {
|
impl_openapi_type!(Vec<T: OpenapiType> => array_schema::<T>(false));
|
||||||
fn schema() -> OpenapiSchema {
|
impl_openapi_type!(BTreeSet<T: OpenapiType>, IndexSet<T: OpenapiType>, HashSet<T: OpenapiType, S: BuildHasher> => {
|
||||||
<Vec<T> as OpenapiType>::schema()
|
array_schema::<T>(true)
|
||||||
}
|
});
|
||||||
}
|
|
||||||
|
|
||||||
impl<T: OpenapiType, S: BuildHasher> OpenapiType for HashSet<T, S> {
|
#[inline]
|
||||||
fn schema() -> OpenapiSchema {
|
fn map_schema<K: OpenapiType, T: OpenapiType>() -> OpenapiSchema {
|
||||||
<Vec<T> as OpenapiType>::schema()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<K: OpenapiType, T: OpenapiType, S: BuildHasher> OpenapiType for HashMap<K, T, S> {
|
|
||||||
fn schema() -> OpenapiSchema {
|
|
||||||
let key_schema = K::schema();
|
let key_schema = K::schema();
|
||||||
let mut dependencies = key_schema.dependencies.clone();
|
let mut dependencies = key_schema.dependencies.clone();
|
||||||
|
|
||||||
|
@ -306,16 +214,11 @@ impl<K: OpenapiType, T: OpenapiType, S: BuildHasher> OpenapiType for HashMap<K,
|
||||||
})),
|
})),
|
||||||
dependencies
|
dependencies
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl OpenapiType for serde_json::Value {
|
impl_openapi_type!(
|
||||||
fn schema() -> OpenapiSchema {
|
BTreeMap<K: OpenapiType, T: OpenapiType>,
|
||||||
OpenapiSchema {
|
IndexMap<K: OpenapiType, T: OpenapiType>,
|
||||||
nullable: true,
|
HashMap<K: OpenapiType, T: OpenapiType, S: BuildHasher>
|
||||||
name: None,
|
=> map_schema::<K, T>()
|
||||||
schema: SchemaKind::Any(Default::default()),
|
);
|
||||||
dependencies: Default::default()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
216
openapi_type/tests/std_types.rs
Normal file
216
openapi_type/tests/std_types.rs
Normal file
|
@ -0,0 +1,216 @@
|
||||||
|
#[cfg(feature = "chrono")]
|
||||||
|
use chrono::{Date, DateTime, FixedOffset, Local, NaiveDate, NaiveDateTime, Utc};
|
||||||
|
use indexmap::{IndexMap, IndexSet};
|
||||||
|
use openapi_type::OpenapiType;
|
||||||
|
use serde_json::Value;
|
||||||
|
use std::{
|
||||||
|
collections::{BTreeMap, BTreeSet, HashMap, HashSet},
|
||||||
|
num::{NonZeroU128, NonZeroU16, NonZeroU32, NonZeroU64, NonZeroU8, NonZeroUsize}
|
||||||
|
};
|
||||||
|
#[cfg(feature = "uuid")]
|
||||||
|
use uuid::Uuid;
|
||||||
|
|
||||||
|
macro_rules! test_type {
|
||||||
|
($($ty:ident $(<$($generic:ident),+>)*),* = $json:tt) => {
|
||||||
|
paste::paste! { $(
|
||||||
|
#[test]
|
||||||
|
fn [< $ty:lower $($(_ $generic:lower)+)* >]() {
|
||||||
|
let schema = <$ty $(<$($generic),+>)* as OpenapiType>::schema();
|
||||||
|
let schema = openapi_type::OpenapiSchema::into_schema(schema);
|
||||||
|
let schema_json = serde_json::to_value(&schema).unwrap();
|
||||||
|
let expected = serde_json::json!($json);
|
||||||
|
assert_eq!(schema_json, expected);
|
||||||
|
}
|
||||||
|
)* }
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
type Unit = ();
|
||||||
|
test_type!(Unit = {
|
||||||
|
"type": "object",
|
||||||
|
"additionalProperties": false
|
||||||
|
});
|
||||||
|
|
||||||
|
test_type!(Value = {
|
||||||
|
"nullable": true
|
||||||
|
});
|
||||||
|
|
||||||
|
test_type!(bool = {
|
||||||
|
"type": "boolean"
|
||||||
|
});
|
||||||
|
|
||||||
|
// ### integer types
|
||||||
|
|
||||||
|
test_type!(isize = {
|
||||||
|
"type": "integer"
|
||||||
|
});
|
||||||
|
|
||||||
|
test_type!(usize = {
|
||||||
|
"type": "integer",
|
||||||
|
"minimum": 0
|
||||||
|
});
|
||||||
|
|
||||||
|
test_type!(i8 = {
|
||||||
|
"type": "integer",
|
||||||
|
"format": "int8"
|
||||||
|
});
|
||||||
|
|
||||||
|
test_type!(u8 = {
|
||||||
|
"type": "integer",
|
||||||
|
"format": "int8",
|
||||||
|
"minimum": 0
|
||||||
|
});
|
||||||
|
|
||||||
|
test_type!(i16 = {
|
||||||
|
"type": "integer",
|
||||||
|
"format": "int16"
|
||||||
|
});
|
||||||
|
|
||||||
|
test_type!(u16 = {
|
||||||
|
"type": "integer",
|
||||||
|
"format": "int16",
|
||||||
|
"minimum": 0
|
||||||
|
});
|
||||||
|
|
||||||
|
test_type!(i32 = {
|
||||||
|
"type": "integer",
|
||||||
|
"format": "int32"
|
||||||
|
});
|
||||||
|
|
||||||
|
test_type!(u32 = {
|
||||||
|
"type": "integer",
|
||||||
|
"format": "int32",
|
||||||
|
"minimum": 0
|
||||||
|
});
|
||||||
|
|
||||||
|
test_type!(i64 = {
|
||||||
|
"type": "integer",
|
||||||
|
"format": "int64"
|
||||||
|
});
|
||||||
|
|
||||||
|
test_type!(u64 = {
|
||||||
|
"type": "integer",
|
||||||
|
"format": "int64",
|
||||||
|
"minimum": 0
|
||||||
|
});
|
||||||
|
|
||||||
|
test_type!(i128 = {
|
||||||
|
"type": "integer",
|
||||||
|
"format": "int128"
|
||||||
|
});
|
||||||
|
|
||||||
|
test_type!(u128 = {
|
||||||
|
"type": "integer",
|
||||||
|
"format": "int128",
|
||||||
|
"minimum": 0
|
||||||
|
});
|
||||||
|
|
||||||
|
// ### non-zero integer types
|
||||||
|
|
||||||
|
test_type!(NonZeroUsize = {
|
||||||
|
"type": "integer",
|
||||||
|
"minimum": 1
|
||||||
|
});
|
||||||
|
|
||||||
|
test_type!(NonZeroU8 = {
|
||||||
|
"type": "integer",
|
||||||
|
"format": "int8",
|
||||||
|
"minimum": 1
|
||||||
|
});
|
||||||
|
|
||||||
|
test_type!(NonZeroU16 = {
|
||||||
|
"type": "integer",
|
||||||
|
"format": "int16",
|
||||||
|
"minimum": 1
|
||||||
|
});
|
||||||
|
|
||||||
|
test_type!(NonZeroU32 = {
|
||||||
|
"type": "integer",
|
||||||
|
"format": "int32",
|
||||||
|
"minimum": 1
|
||||||
|
});
|
||||||
|
|
||||||
|
test_type!(NonZeroU64 = {
|
||||||
|
"type": "integer",
|
||||||
|
"format": "int64",
|
||||||
|
"minimum": 1
|
||||||
|
});
|
||||||
|
|
||||||
|
test_type!(NonZeroU128 = {
|
||||||
|
"type": "integer",
|
||||||
|
"format": "int128",
|
||||||
|
"minimum": 1
|
||||||
|
});
|
||||||
|
|
||||||
|
// ### floats
|
||||||
|
|
||||||
|
test_type!(f32 = {
|
||||||
|
"type": "number",
|
||||||
|
"format": "float"
|
||||||
|
});
|
||||||
|
|
||||||
|
test_type!(f64 = {
|
||||||
|
"type": "number",
|
||||||
|
"format": "double"
|
||||||
|
});
|
||||||
|
|
||||||
|
// ### string
|
||||||
|
|
||||||
|
test_type!(String = {
|
||||||
|
"type": "string"
|
||||||
|
});
|
||||||
|
|
||||||
|
#[cfg(feature = "uuid")]
|
||||||
|
test_type!(Uuid = {
|
||||||
|
"type": "string",
|
||||||
|
"format": "uuid"
|
||||||
|
});
|
||||||
|
|
||||||
|
// ### date/time
|
||||||
|
|
||||||
|
#[cfg(feature = "chrono")]
|
||||||
|
test_type!(Date<FixedOffset>, Date<Local>, Date<Utc>, NaiveDate = {
|
||||||
|
"type": "string",
|
||||||
|
"format": "date"
|
||||||
|
});
|
||||||
|
|
||||||
|
#[cfg(feature = "chrono")]
|
||||||
|
test_type!(DateTime<FixedOffset>, DateTime<Local>, DateTime<Utc>, NaiveDateTime = {
|
||||||
|
"type": "string",
|
||||||
|
"format": "date-time"
|
||||||
|
});
|
||||||
|
|
||||||
|
// ### some std types
|
||||||
|
|
||||||
|
test_type!(Option<String> = {
|
||||||
|
"type": "string",
|
||||||
|
"nullable": true
|
||||||
|
});
|
||||||
|
|
||||||
|
test_type!(Vec<String> = {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
test_type!(BTreeSet<String>, IndexSet<String>, HashSet<String> = {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"uniqueItems": true
|
||||||
|
});
|
||||||
|
|
||||||
|
test_type!(BTreeMap<isize, String>, IndexMap<isize, String>, HashMap<isize, String> = {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"default": {
|
||||||
|
"type": "integer"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": ["default"],
|
||||||
|
"additionalProperties": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
});
|
|
@ -7,7 +7,6 @@ use openapiv3::{
|
||||||
ReferenceOr::{Item, Reference},
|
ReferenceOr::{Item, Reference},
|
||||||
Schema, SchemaData, SchemaKind, StringType, Type, VariantOrUnknownOrEmpty
|
Schema, SchemaData, SchemaKind, StringType, Type, VariantOrUnknownOrEmpty
|
||||||
};
|
};
|
||||||
|
|
||||||
use std::{
|
use std::{
|
||||||
collections::{BTreeSet, HashMap, HashSet},
|
collections::{BTreeSet, HashMap, HashSet},
|
||||||
hash::BuildHasher,
|
hash::BuildHasher,
|
||||||
|
|
Loading…
Add table
Reference in a new issue