Fix skip_serializing_if/serialize_with handling

Previously whenever a field with a default value has both `skip_serializing_if` and `with`/`serialize_with` attributes, the value would be converted to a type that performs the custom serialization before checking if it should be serialized. This would cause the wrong type to be given to the skip_serializing_if function, causing a compile error.

Issue #26
This commit is contained in:
Graham Esau 2020-04-11 22:06:48 +01:00
parent d1f2c0f803
commit 63af0ceb73
7 changed files with 54 additions and 42 deletions

View file

@ -316,7 +316,6 @@ fn schema_for_struct(fields: &[Field], cattrs: Option<&serde_attr::Container>) -
read_only: field.attrs.skip_deserializing(),
write_only: field.attrs.skip_serializing(),
default,
skip_default_if: field.attrs.skip_serializing_if().cloned(),
..SchemaMetadata::from_doc_attrs(&field.original.attrs)
};
@ -367,6 +366,22 @@ fn field_default_expr(field: &Field, container_has_default: bool) -> Option<Toke
SerdeDefault::Path(path) => quote!(#path()),
};
let default_expr = match field.attrs.skip_serializing_if() {
Some(skip_if) => {
quote! {
{
let default = #default_expr;
if #skip_if(&default) {
None
} else {
Some(default)
}
}
}
}
None => quote!(Some(#default_expr)),
};
Some(if let Some(ser_with) = field.attrs.serialize_with() {
quote! {
{
@ -382,7 +397,7 @@ fn field_default_expr(field: &Field, container_has_default: bool) -> Option<Toke
}
}
_SchemarsDefaultSerialize(#default_expr)
#default_expr.map(|d| _SchemarsDefaultSerialize(d))
}
}
} else {