Enable deriving JsonSchema for unit/newtype/tuple structs

This commit is contained in:
Graham Esau 2019-09-07 16:36:12 +01:00
parent 07f4f68a02
commit 3f5f7cf0a3
6 changed files with 107 additions and 18 deletions

View file

@ -0,0 +1,5 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "Newtype",
"type": "integer"
}

View file

@ -0,0 +1,17 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "Struct",
"type": "object",
"properties": {
"bar": {
"type": "boolean"
},
"foo": {
"type": "integer"
}
},
"required": [
"bar",
"foo"
]
}

View file

@ -0,0 +1,15 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "Tuple",
"type": "array",
"items": [
{
"type": "integer"
},
{
"type": "boolean"
}
],
"maxItems": 2,
"minItems": 2
}

View file

@ -0,0 +1,5 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "Unit",
"type": "null"
}

38
schemars/tests/struct.rs Normal file
View file

@ -0,0 +1,38 @@
mod util;
use schemars::JsonSchema;
use util::*;
#[derive(Debug, JsonSchema)]
pub struct Struct {
foo: i32,
bar: bool,
}
#[test]
fn struct_normal() -> TestResult {
test_default_generated_schema::<Struct>("struct-normal")
}
#[derive(Debug, JsonSchema)]
pub struct Tuple(i32, bool);
#[test]
fn struct_tuple() -> TestResult {
test_default_generated_schema::<Tuple>("struct-tuple")
}
#[derive(Debug, JsonSchema)]
pub struct Newtype(i32);
#[test]
fn struct_newtype() -> TestResult {
test_default_generated_schema::<Newtype>("struct-newtype")
}
#[derive(Debug, JsonSchema)]
pub struct Unit;
#[test]
fn struct_unit() -> TestResult {
test_default_generated_schema::<Unit>("struct-unit")
}

View file

@ -28,9 +28,11 @@ pub fn derive_json_schema(input: proc_macro::TokenStream) -> proc_macro::TokenSt
}
let schema = match cont.data {
Data::Struct(Style::Unit, _) => schema_for_unit_struct(),
Data::Struct(Style::Newtype, ref fields) => schema_for_newtype_struct(&fields[0]),
Data::Struct(Style::Tuple, ref fields) => schema_for_tuple_struct(fields),
Data::Struct(Style::Struct, ref fields) => schema_for_struct(fields, &cont.attrs),
Data::Enum(ref variants) => schema_for_enum(variants, &cont.attrs),
_ => unimplemented!("work in progress!"),
};
let type_name = cont.ident;
@ -105,7 +107,7 @@ fn schema_for_enum(variants: &[Variant], cattrs: &attr::Container) -> TokenStrea
EnumTag::External => schema_for_external_tagged_enum(variants, cattrs),
EnumTag::None => schema_for_untagged_enum(variants, cattrs),
EnumTag::Internal { tag } => schema_for_internal_tagged_enum(variants, cattrs, tag),
EnumTag::Adjacent => unimplemented!("Adjacent tagged enums not yet supported."),
EnumTag::Adjacent { .. } => unimplemented!("Adjacent tagged enums not yet supported."),
}
}
@ -204,24 +206,31 @@ fn schema_for_untagged_enum(variants: &[Variant], cattrs: &attr::Container) -> T
fn schema_for_untagged_enum_variant(variant: &Variant, cattrs: &attr::Container) -> TokenStream {
match variant.style {
Style::Unit => quote! {
Style::Unit => schema_for_unit_struct(),
Style::Newtype => schema_for_newtype_struct(&variant.fields[0]),
Style::Tuple => schema_for_tuple_struct(&variant.fields),
Style::Struct => schema_for_struct(&variant.fields, cattrs),
}
}
fn schema_for_unit_struct() -> TokenStream {
quote! {
gen.subschema_for::<()>()?
},
Style::Newtype => {
let f = &variant.fields[0];
let ty = f.ty;
quote_spanned! {f.original.span()=>
}
}
fn schema_for_newtype_struct(field: &Field) -> TokenStream {
let ty = field.ty;
quote_spanned! {field.original.span()=>
gen.subschema_for::<#ty>()?
}
}
Style::Tuple => {
let types = variant.fields.iter().map(|f| f.ty);
}
fn schema_for_tuple_struct(fields: &[Field]) -> TokenStream {
let types = fields.iter().map(|f| f.ty);
quote! {
gen.subschema_for::<(#(#types),*)>()?
}
}
Style::Struct => schema_for_struct(&variant.fields, cattrs),
}
}
fn schema_for_struct(fields: &[Field], cattrs: &attr::Container) -> TokenStream {