Pass fewer attributes to serde_derive_internals

This commit is contained in:
Graham Esau 2019-12-09 18:43:43 +00:00
parent 3e5a054793
commit dca9e2d920

View file

@ -1,30 +1,30 @@
use quote::ToTokens; use quote::ToTokens;
use serde_derive_internals::Ctxt; use serde_derive_internals::Ctxt;
use std::collections::BTreeSet; use std::collections::HashSet;
use syn::parse::Parser; use syn::parse::Parser;
use syn::{Attribute, Data, DeriveInput, Field, GenericParam, Generics, Meta, NestedMeta, Variant}; use syn::{Attribute, Data, DeriveInput, Field, GenericParam, Generics, Meta, NestedMeta, Variant};
// List of keywords that can appear in #[serde(...)]/#[schemars(...)] attributes, which we want serde to parse for us. // List of keywords that can appear in #[serde(...)]/#[schemars(...)] attributes which we want serde_derive_internals to parse for us.
static SERDE_KEYWORDS: &[&str] = &[ static SERDE_KEYWORDS: &[&str] = &[
"rename", "rename",
"rename_all", "rename_all",
"deny_unknown_fields", // TODO: for structs with `deny_unknown_fields`, set schema's `additionalProperties` to false.
// "deny_unknown_fields",
"tag", "tag",
"content", // TODO: support adjecently tagged enums (https://github.com/GREsau/schemars/issues/4)
// "content",
"untagged", "untagged",
"bound",
"default", "default",
"remote",
"alias",
"skip", "skip",
"skip_serializing", "skip_serializing",
"skip_serializing_if", "skip_serializing_if",
"skip_deserializing", "skip_deserializing",
"other",
"flatten", "flatten",
// special cases - these keywords are not copied from schemars attrs to serde attrs // Special cases - `with`/`serialize_with` are passed to serde but not copied from schemars attrs to serde attrs.
// This is because we want to preserve any serde attribute's `serialize_with` value to determine whether the field's
// default value should be serialized. We also check the `with` value on schemars/serde attrs e.g. to support deriving
// JsonSchema on remote types, but we parse that ourselves rather than using serde_derive_internals.
"serialize_with", "serialize_with",
"deserialize_with",
"with", "with",
]; ];
@ -36,8 +36,8 @@ pub fn add_trait_bounds(generics: &mut Generics) {
} }
} }
// If a struct/variant/field has any #[schemars] attributes, then rename them // If a struct/variant/field has any #[schemars] attributes, then create copies of them
// to #[serde] so that serde_derive_internals will parse them for us. // as #[serde] attributes so that serde_derive_internals will parse them for us.
pub fn process_serde_attrs(input: &mut DeriveInput) -> Result<(), Vec<syn::Error>> { pub fn process_serde_attrs(input: &mut DeriveInput) -> Result<(), Vec<syn::Error>> {
let ctxt = Ctxt::new(); let ctxt = Ctxt::new();
process_attrs(&ctxt, &mut input.attrs); process_attrs(&ctxt, &mut input.attrs);
@ -74,7 +74,7 @@ fn process_attrs(ctxt: &Ctxt, attrs: &mut Vec<Attribute>) {
.filter(|at| at.path.is_ident("schemars")) .filter(|at| at.path.is_ident("schemars"))
.collect(); .collect();
let (mut serde_meta, mut schemars_meta_names): (Vec<_>, BTreeSet<_>) = schemars_attrs let (mut serde_meta, mut schemars_meta_names): (Vec<_>, HashSet<_>) = schemars_attrs
.iter() .iter()
.flat_map(|at| get_meta_items(&ctxt, at)) .flat_map(|at| get_meta_items(&ctxt, at))
.flatten() .flatten()
@ -171,7 +171,7 @@ mod tests {
#[misc] #[misc]
struct MyStruct { struct MyStruct {
/// blah blah blah /// blah blah blah
#[serde(alias = "first")] #[serde(skip_serializing_if = "some_fn")]
field1: i32, field1: i32,
#[serde(serialize_with = "se", deserialize_with = "de")] #[serde(serialize_with = "se", deserialize_with = "de")]
#[schemars(with = "with")] #[schemars(with = "with")]
@ -187,10 +187,10 @@ mod tests {
#[serde(rename = "overriden", rename_all = "camelCase", default)] #[serde(rename = "overriden", rename_all = "camelCase", default)]
struct MyStruct { struct MyStruct {
#[doc = r" blah blah blah"] #[doc = r" blah blah blah"]
#[serde(alias = "first")] #[serde(skip_serializing_if = "some_fn")]
field1: i32, field1: i32,
#[schemars(with = "with")] #[schemars(with = "with")]
#[serde(serialize_with = "se", deserialize_with = "de")] #[serde(serialize_with = "se")]
field2: i32, field2: i32,
#[schemars(skip)] #[schemars(skip)]
#[serde(skip)] #[serde(skip)]