Do not pass container attributes through enums/variants
When deriving JsonSchema over a struct-style enum variant, do not apply the enum's container attributes to the variant. This couldn't cause any problems in practice because the only container attribute we explicitly set is "default", which cannot be set on an enum.
This commit is contained in:
parent
fc592e5dd7
commit
d30238c981
1 changed files with 13 additions and 17 deletions
|
@ -35,7 +35,7 @@ pub fn derive_json_schema(input: proc_macro::TokenStream) -> proc_macro::TokenSt
|
||||||
Data::Struct(Style::Unit, _) => schema_for_unit_struct(),
|
Data::Struct(Style::Unit, _) => schema_for_unit_struct(),
|
||||||
Data::Struct(Style::Newtype, ref fields) => schema_for_newtype_struct(&fields[0]),
|
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::Tuple, ref fields) => schema_for_tuple_struct(fields),
|
||||||
Data::Struct(Style::Struct, ref fields) => schema_for_struct(fields, &cont.attrs),
|
Data::Struct(Style::Struct, ref fields) => schema_for_struct(fields, Some(&cont.attrs)),
|
||||||
Data::Enum(ref variants) => schema_for_enum(variants, &cont.attrs),
|
Data::Enum(ref variants) => schema_for_enum(variants, &cont.attrs),
|
||||||
};
|
};
|
||||||
let schema_expr = set_metadata_on_schema_from_docs(schema_expr, &cont.original.attrs);
|
let schema_expr = set_metadata_on_schema_from_docs(schema_expr, &cont.original.attrs);
|
||||||
|
@ -117,16 +117,15 @@ fn is_unit_variant(v: &Variant) -> bool {
|
||||||
fn schema_for_enum(variants: &[Variant], cattrs: &serde_attr::Container) -> TokenStream {
|
fn schema_for_enum(variants: &[Variant], cattrs: &serde_attr::Container) -> TokenStream {
|
||||||
let variants = variants.iter().filter(|v| !v.attrs.skip_deserializing());
|
let variants = variants.iter().filter(|v| !v.attrs.skip_deserializing());
|
||||||
match cattrs.tag() {
|
match cattrs.tag() {
|
||||||
TagType::External => schema_for_external_tagged_enum(variants, cattrs),
|
TagType::External => schema_for_external_tagged_enum(variants),
|
||||||
TagType::None => schema_for_untagged_enum(variants, cattrs),
|
TagType::None => schema_for_untagged_enum(variants),
|
||||||
TagType::Internal { tag } => schema_for_internal_tagged_enum(variants, cattrs, tag),
|
TagType::Internal { tag } => schema_for_internal_tagged_enum(variants, tag),
|
||||||
TagType::Adjacent { .. } => unimplemented!("Adjacent tagged enums not yet supported."),
|
TagType::Adjacent { .. } => unimplemented!("Adjacent tagged enums not yet supported."),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn schema_for_external_tagged_enum<'a>(
|
fn schema_for_external_tagged_enum<'a>(
|
||||||
variants: impl Iterator<Item = &'a Variant<'a>>,
|
variants: impl Iterator<Item = &'a Variant<'a>>
|
||||||
cattrs: &serde_attr::Container,
|
|
||||||
) -> TokenStream {
|
) -> TokenStream {
|
||||||
let (unit_variants, complex_variants): (Vec<_>, Vec<_>) =
|
let (unit_variants, complex_variants): (Vec<_>, Vec<_>) =
|
||||||
variants.partition(|v| is_unit_variant(v));
|
variants.partition(|v| is_unit_variant(v));
|
||||||
|
@ -150,7 +149,7 @@ fn schema_for_external_tagged_enum<'a>(
|
||||||
|
|
||||||
schemas.extend(complex_variants.into_iter().map(|variant| {
|
schemas.extend(complex_variants.into_iter().map(|variant| {
|
||||||
let name = variant.attrs.name().deserialize_name();
|
let name = variant.attrs.name().deserialize_name();
|
||||||
let sub_schema = schema_for_untagged_enum_variant(variant, cattrs);
|
let sub_schema = schema_for_untagged_enum_variant(variant);
|
||||||
let schema_expr = wrap_schema_fields(quote! {
|
let schema_expr = wrap_schema_fields(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 {
|
||||||
|
@ -180,7 +179,6 @@ fn schema_for_external_tagged_enum<'a>(
|
||||||
|
|
||||||
fn schema_for_internal_tagged_enum<'a>(
|
fn schema_for_internal_tagged_enum<'a>(
|
||||||
variants: impl Iterator<Item = &'a Variant<'a>>,
|
variants: impl Iterator<Item = &'a Variant<'a>>,
|
||||||
cattrs: &serde_attr::Container,
|
|
||||||
tag_name: &str,
|
tag_name: &str,
|
||||||
) -> TokenStream {
|
) -> TokenStream {
|
||||||
let schemas = variants.map(|variant| {
|
let schemas = variants.map(|variant| {
|
||||||
|
@ -217,7 +215,7 @@ fn schema_for_internal_tagged_enum<'a>(
|
||||||
<#ty>::json_schema(gen)
|
<#ty>::json_schema(gen)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Style::Struct => schema_for_struct(&variant.fields, cattrs),
|
Style::Struct => schema_for_struct(&variant.fields, None),
|
||||||
Style::Tuple => unreachable!("Internal tagged enum tuple variants will have caused serde_derive_internals to output a compile error already."),
|
Style::Tuple => unreachable!("Internal tagged enum tuple variants will have caused serde_derive_internals to output a compile error already."),
|
||||||
};
|
};
|
||||||
quote! {
|
quote! {
|
||||||
|
@ -234,11 +232,10 @@ fn schema_for_internal_tagged_enum<'a>(
|
||||||
}
|
}
|
||||||
|
|
||||||
fn schema_for_untagged_enum<'a>(
|
fn schema_for_untagged_enum<'a>(
|
||||||
variants: impl Iterator<Item = &'a Variant<'a>>,
|
variants: impl Iterator<Item = &'a Variant<'a>>
|
||||||
cattrs: &serde_attr::Container,
|
|
||||||
) -> TokenStream {
|
) -> TokenStream {
|
||||||
let schemas = variants.map(|variant| {
|
let schemas = variants.map(|variant| {
|
||||||
let schema_expr = schema_for_untagged_enum_variant(variant, cattrs);
|
let schema_expr = schema_for_untagged_enum_variant(variant);
|
||||||
set_metadata_on_schema_from_docs(schema_expr, &variant.original.attrs)
|
set_metadata_on_schema_from_docs(schema_expr, &variant.original.attrs)
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -251,14 +248,13 @@ fn schema_for_untagged_enum<'a>(
|
||||||
}
|
}
|
||||||
|
|
||||||
fn schema_for_untagged_enum_variant(
|
fn schema_for_untagged_enum_variant(
|
||||||
variant: &Variant,
|
variant: &Variant
|
||||||
cattrs: &serde_attr::Container,
|
|
||||||
) -> TokenStream {
|
) -> TokenStream {
|
||||||
match variant.style {
|
match variant.style {
|
||||||
Style::Unit => schema_for_unit_struct(),
|
Style::Unit => schema_for_unit_struct(),
|
||||||
Style::Newtype => schema_for_newtype_struct(&variant.fields[0]),
|
Style::Newtype => schema_for_newtype_struct(&variant.fields[0]),
|
||||||
Style::Tuple => schema_for_tuple_struct(&variant.fields),
|
Style::Tuple => schema_for_tuple_struct(&variant.fields),
|
||||||
Style::Struct => schema_for_struct(&variant.fields, cattrs),
|
Style::Struct => schema_for_struct(&variant.fields, None),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -285,13 +281,13 @@ fn schema_for_tuple_struct(fields: &[Field]) -> TokenStream {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn schema_for_struct(fields: &[Field], cattrs: &serde_attr::Container) -> TokenStream {
|
fn schema_for_struct(fields: &[Field], cattrs: Option<&serde_attr::Container>) -> TokenStream {
|
||||||
let (flat, nested): (Vec<_>, Vec<_>) = fields
|
let (flat, nested): (Vec<_>, Vec<_>) = fields
|
||||||
.iter()
|
.iter()
|
||||||
.filter(|f| !f.attrs.skip_deserializing() || !f.attrs.skip_serializing())
|
.filter(|f| !f.attrs.skip_deserializing() || !f.attrs.skip_serializing())
|
||||||
.partition(|f| f.attrs.flatten());
|
.partition(|f| f.attrs.flatten());
|
||||||
|
|
||||||
let set_container_default = match cattrs.default() {
|
let set_container_default = match cattrs.map_or(&SerdeDefault::None, |c| c.default()) {
|
||||||
SerdeDefault::None => None,
|
SerdeDefault::None => None,
|
||||||
SerdeDefault::Default => Some(quote!(let container_default = Self::default();)),
|
SerdeDefault::Default => Some(quote!(let container_default = Self::default();)),
|
||||||
SerdeDefault::Path(path) => Some(quote!(let container_default = #path();)),
|
SerdeDefault::Path(path) => Some(quote!(let container_default = #path();)),
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue