Closed jonasbb closed 1 year ago
A supplemental use-case for this is a companion to skip_serializing_none
: APIs which need that (e.g. JSON swagger / openapi) tend to need skip_serializing_if = "Option::is_none"
on the serialization side, but also default
on the deserialization side.
skip_serializing_none
only covers the first one, so when one needs to handle both sides of the serialization (sometimes on the same struct e.g. because it's defined for both the client and server to use) it can be a bit frustrating.
Possible issues with this:
#[serde]
annotations per field? What if a user needs both a blanket annotation, and a specific annotation on a specific field (e.g. rename
)?I guess the macro could just bail (refuse to compile) if it sees a #[serde]
annotation on a field it tries to configure, seems safer than trying to mess around even if it means the user is back to hand-rolling the entire thing.
A supplemental use-case for this is a companion to
skip_serializing_none
: APIs which need that (e.g. JSON swagger / openapi) tend to needskip_serializing_if = "Option::is_none"
on the serialization side, but alsodefault
on the deserialization side.
You do not need default
on a field of type Option
. Missing fields automatically default to None
. The exception is if you use #[serde(with = ...)]
or #[serde_as(...)]
. In the first case using default
changes the meaning, and the second case is tracked here #185.
- does serde allow multple
#[serde]
annotations per field? What if a user needs both a blanket annotation, and a specific annotation on a specific field (e.g.rename
)?
Multiple annotations work flawlessly. Their individual meanings get joined.
- what about reverting the behaviour for one specific field? e.g. if the user wants to bulk-apply "skip empty collections" but one or two of them must be serialised empty? Or an API which mixes optional fields (skipped) and required nullable fields (not skipped)?
Similar to skip_serializing_none
a simple #[no_apply]
probably makes sense. It should mark the field to be ignored for any apply
macro. Having two #[apply]
apply on one type is probably rare, and even rarer that they overlap but you only want to opt-out of one apply
. In such corner cases, all attributes can always be applied manually on the fields.
I guess the macro could just bail (refuse to compile) if it sees a
#[serde]
annotation on a field it tries to configure, seems safer than trying to mess around even if it means the user is back to hand-rolling the entire thing.
I would not want the apply
macro to parse any annotations not meant for it. This means if there is already a #[serde]
on the field, that shouldn't bother the apply
macro. If any other macros or derives cannot handle that, then that is a user/other crate problem. The reason here is simply that the annotation to be applied on the field does not have to be serde related. It could also be for any other derive. So erroring, if there is a #[serde]
annotation, is wrong.
A supplemental use-case for this is a companion to
skip_serializing_none
: APIs which need that (e.g. JSON swagger / openapi) tend to needskip_serializing_if = "Option::is_none"
on the serialization side, but alsodefault
on the deserialization side.You do not need
default
on a field of typeOption
. Missing fields automatically default toNone
.
Well now I'm astonished, I was convinced it'd yield a parsing error.
That is rather convenient, thank you very much.
This is available since a bit as serde_with::apply
.
Serialization code is often repetitive. One helper to improve on this already exists in this crate, the
serde_with::skip_serializing_none
attribute.However, this could be generalized to work with any attribute on a user-specified type (list). This could look like
This would apply the attribute on all fields of type
Vec
andHashMap
. On the right hand side, the placeholder$TYPE
would be replaced by the type of the field. This would make it easier to skip serializing all empty container types.serde_with::skip_serializing_none
could in the end be implemented on top of this more general proc-macro.