Fix handling of attributes applied to unit variant types (#152)

This commit is contained in:
Adam Leventhal 2022-08-12 07:37:34 -07:00 committed by GitHub
parent 9464118c3a
commit 76427ef384
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 109 additions and 28 deletions

View file

@ -31,7 +31,8 @@ struct MyUnitStruct;
#[doc = " the enum's description."] #[doc = " the enum's description."]
enum MyEnum { enum MyEnum {
UndocumentedUnit, UndocumentedUnit,
/// This comment is not included in the generated schema :( UndocumentedUnit2,
/// This comment is included in the generated schema :)
DocumentedUnit, DocumentedUnit,
/// ## Complex variant /// ## Complex variant
/// This is a struct-like variant. /// This is a struct-like variant.

View file

@ -118,3 +118,21 @@ enum SimpleInternal {
fn enum_simple_internal_tag() -> TestResult { fn enum_simple_internal_tag() -> TestResult {
test_default_generated_schema::<SimpleInternal>("enum-simple-internal") test_default_generated_schema::<SimpleInternal>("enum-simple-internal")
} }
#[allow(dead_code)]
#[derive(JsonSchema)]
enum SoundOfMusic {
/// # A deer
///
/// A female deer
Do,
/// A drop of golden sun
Re,
/// A name I call myself
Mi,
}
#[test]
fn enum_unit_with_doc_comments() -> TestResult {
test_default_generated_schema::<SoundOfMusic>("enum-unit-doc")
}

View file

@ -6,7 +6,13 @@
{ {
"type": "string", "type": "string",
"enum": [ "enum": [
"Unit", "Unit"
]
},
{
"deprecated": true,
"type": "string",
"enum": [
"DeprecatedUnitVariant" "DeprecatedUnitVariant"
] ]
}, },

View file

@ -7,6 +7,13 @@
"type": "string", "type": "string",
"enum": [ "enum": [
"UndocumentedUnit", "UndocumentedUnit",
"UndocumentedUnit2"
]
},
{
"description": "This comment is included in the generated schema :)",
"type": "string",
"enum": [
"DocumentedUnit" "DocumentedUnit"
] ]
}, },

View file

@ -0,0 +1,28 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "SoundOfMusic",
"oneOf": [
{
"title": "A deer",
"description": "A female deer",
"type": "string",
"enum": [
"Do"
]
},
{
"description": "A drop of golden sun",
"type": "string",
"enum": [
"Re"
]
},
{
"description": "A name I call myself",
"type": "string",
"enum": [
"Mi"
]
}
]
}

View file

@ -185,6 +185,21 @@ impl Attrs {
} }
self self
} }
pub fn is_default(&self) -> bool {
match self {
Self {
with: None,
title: None,
description: None,
deprecated: false,
examples,
repr: None,
crate_name: None,
} if examples.is_empty() => true,
_ => false,
}
}
} }
fn is_known_serde_or_validation_keyword(meta: &syn::Meta) -> bool { fn is_known_serde_or_validation_keyword(meta: &syn::Meta) -> bool {

View file

@ -149,8 +149,7 @@ fn expr_for_external_tagged_enum<'a>(
unique_names.insert(v.name()); unique_names.insert(v.name());
count += 1; count += 1;
}) })
.partition(|v| v.is_unit() && v.attrs.with.is_none()); .partition(|v| v.is_unit() && v.attrs.is_default());
let unit_names = unit_variants.iter().map(|v| v.name()); let unit_names = unit_variants.iter().map(|v| v.name());
let unit_schema = schema_object(quote! { let unit_schema = schema_object(quote! {
instance_type: Some(schemars::schema::InstanceType::String.into()), instance_type: Some(schemars::schema::InstanceType::String.into()),
@ -168,9 +167,15 @@ fn expr_for_external_tagged_enum<'a>(
schemas.extend(complex_variants.into_iter().map(|variant| { schemas.extend(complex_variants.into_iter().map(|variant| {
let name = variant.name(); let name = variant.name();
let sub_schema = expr_for_untagged_enum_variant(variant, deny_unknown_fields);
let mut schema_expr = schema_object(quote! { let mut schema_expr = if variant.is_unit() && variant.attrs.with.is_none() {
schema_object(quote! {
instance_type: Some(schemars::schema::InstanceType::String.into()),
enum_values: Some(vec![#name.into()]),
})
} else {
let sub_schema = expr_for_untagged_enum_variant(variant, deny_unknown_fields);
schema_object(quote! {
instance_type: Some(schemars::schema::InstanceType::Object.into()), instance_type: Some(schemars::schema::InstanceType::Object.into()),
object: Some(Box::new(schemars::schema::ObjectValidation { object: Some(Box::new(schemars::schema::ObjectValidation {
properties: { properties: {
@ -192,7 +197,8 @@ fn expr_for_external_tagged_enum<'a>(
additional_properties: Some(Box::new(false.into())), additional_properties: Some(Box::new(false.into())),
..Default::default() ..Default::default()
})), })),
}); })
};
variant variant
.attrs .attrs