From 38c8b2d911cea46a98387ea39ef0d74383cf2a4a Mon Sep 17 00:00:00 2001 From: Graham Esau Date: Sun, 4 Aug 2019 20:43:02 +0100 Subject: [PATCH] Tuples! --- schemars/src/make_schema.rs | 50 +++++++++++++++++++++++++++++++++++-- schemars/src/schema.rs | 22 ++++------------ 2 files changed, 53 insertions(+), 19 deletions(-) diff --git a/schemars/src/make_schema.rs b/schemars/src/make_schema.rs index e53c376..1a210a6 100644 --- a/schemars/src/make_schema.rs +++ b/schemars/src/make_schema.rs @@ -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::())), + items: Some(gen.subschema_for::().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::())), + items: Some(gen.subschema_for::().into()), ..Default::default() }.into() } diff --git a/schemars/src/schema.rs b/schemars/src/schema.rs index 120ef76..cc5b3b9 100644 --- a/schemars/src/schema.rs +++ b/schemars/src/schema.rs @@ -52,7 +52,7 @@ pub struct SchemaObject { #[serde(rename = "enum", skip_serializing_if = "Option::is_none")] pub enum_values: Option>, #[serde(skip_serializing_if = "Option::is_none")] - pub items: Option>, + pub items: Option>, #[serde(skip_serializing_if = "Map::is_empty")] pub properties: Map, #[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 { - Single(T), + Single(Box), Vec(Vec), } impl From for SingleOrVec { fn from(single: T) -> Self { - SingleOrVec::Single(single) + SingleOrVec::Single(Box::new(single)) } } impl From> for SingleOrVec { - fn from(mut vec: Vec) -> Self { - match vec.len() { - 1 => SingleOrVec::Single(vec.remove(0)), - _ => SingleOrVec::Vec(vec), - } - } -} - -impl Into> for SingleOrVec { - fn into(self) -> Vec { - match self { - SingleOrVec::Single(s) => vec![s], - SingleOrVec::Vec(v) => v, - } + fn from(vec: Vec) -> Self { + SingleOrVec::Vec(vec) } }