This commit is contained in:
Graham Esau 2019-08-04 20:43:02 +01:00
parent d1a319c5f2
commit 38c8b2d911
2 changed files with 53 additions and 19 deletions

View file

@ -128,7 +128,7 @@ macro_rules! array_impls {
extensions.insert("maxItems".to_owned(), json!($len));
SchemaObject {
instance_type: Some(InstanceType::Array.into()),
items: Some(Box::from(gen.subschema_for::<T>())),
items: Some(gen.subschema_for::<T>().into()),
extensions,
..Default::default()
}.into()
@ -145,6 +145,52 @@ array_impls! {
31 32
}
////////// TUPLES //////////
macro_rules! tuple_impls {
($($len:expr => ($($name:ident)+))+) => {
$(
impl<$($name: MakeSchema),+> MakeSchema for ($($name,)+) {
no_ref_schema!();
fn make_schema(gen: &mut SchemaGenerator) -> Schema {
let mut extensions = Map::new();
extensions.insert("minItems".to_owned(), json!($len));
extensions.insert("maxItems".to_owned(), json!($len));
let items = vec![
$(gen.subschema_for::<$name>()),+
];
SchemaObject {
instance_type: Some(InstanceType::Array.into()),
items: Some(items.into()),
extensions,
..Default::default()
}.into()
}
}
)+
}
}
tuple_impls! {
1 => (T0)
2 => (T0 T1)
3 => (T0 T1 T2)
4 => (T0 T1 T2 T3)
5 => (T0 T1 T2 T3 T4)
6 => (T0 T1 T2 T3 T4 T5)
7 => (T0 T1 T2 T3 T4 T5 T6)
8 => (T0 T1 T2 T3 T4 T5 T6 T7)
9 => (T0 T1 T2 T3 T4 T5 T6 T7 T8)
10 => (T0 T1 T2 T3 T4 T5 T6 T7 T8 T9)
11 => (T0 T1 T2 T3 T4 T5 T6 T7 T8 T9 T10)
12 => (T0 T1 T2 T3 T4 T5 T6 T7 T8 T9 T10 T11)
13 => (T0 T1 T2 T3 T4 T5 T6 T7 T8 T9 T10 T11 T12)
14 => (T0 T1 T2 T3 T4 T5 T6 T7 T8 T9 T10 T11 T12 T13)
15 => (T0 T1 T2 T3 T4 T5 T6 T7 T8 T9 T10 T11 T12 T13 T14)
16 => (T0 T1 T2 T3 T4 T5 T6 T7 T8 T9 T10 T11 T12 T13 T14 T15)
}
////////// SEQUENCES /////////
macro_rules! seq_impl {
@ -159,7 +205,7 @@ macro_rules! seq_impl {
{
SchemaObject {
instance_type: Some(InstanceType::Array.into()),
items: Some(Box::from(gen.subschema_for::<T>())),
items: Some(gen.subschema_for::<T>().into()),
..Default::default()
}.into()
}

View file

@ -52,7 +52,7 @@ pub struct SchemaObject {
#[serde(rename = "enum", skip_serializing_if = "Option::is_none")]
pub enum_values: Option<Vec<Value>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub items: Option<Box<Schema>>,
pub items: Option<SingleOrVec<Schema>>,
#[serde(skip_serializing_if = "Map::is_empty")]
pub properties: Map<String, Schema>,
#[serde(skip_serializing_if = "Option::is_none")]
@ -86,30 +86,18 @@ pub enum InstanceType {
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
#[serde(untagged)]
pub enum SingleOrVec<T> {
Single(T),
Single(Box<T>),
Vec(Vec<T>),
}
impl<T> From<T> for SingleOrVec<T> {
fn from(single: T) -> Self {
SingleOrVec::Single(single)
SingleOrVec::Single(Box::new(single))
}
}
impl<T> From<Vec<T>> for SingleOrVec<T> {
fn from(mut vec: Vec<T>) -> Self {
match vec.len() {
1 => SingleOrVec::Single(vec.remove(0)),
_ => SingleOrVec::Vec(vec),
}
}
}
impl<T> Into<Vec<T>> for SingleOrVec<T> {
fn into(self) -> Vec<T> {
match self {
SingleOrVec::Single(s) => vec![s],
SingleOrVec::Vec(v) => v,
}
fn from(vec: Vec<T>) -> Self {
SingleOrVec::Vec(vec)
}
}