feat(codegen): Detect repeated struct field when deserializing
Addresses #59. Let me know whether you think we need an escape hatch to opt out of this check.
The generated code for a struct like:
struct Test<A, B, C> {
a: X<A>
#[serde(skip_serializing)]
b: B
#[serde(serialize_with="...")]
c: C
}
Used to be:
impl<A, B, C> Serialize for Test<A, B, C>
where A: Serialize,
B: Serialize,
C: Serialize,
{ ... }
Now it is:
impl<A, B, C> Serialize for Test<A, B, C>
where X<A>: Serialize,
{ ... }
Both `skip_serializing` and `serialize_with` mean the type does not need to
implement `Serialize`.
This allows a field to be deserialized with an expression instead
of the default deserializer. This simplifies deserializing a struct
or enum that contains an external type that doesn't implement
`serde::Deserialize`. This expression is passed a variable
`deserializer` that needs to be used to deserialize the expression.
This allows a field to be serialized with an expression instead
of the default serializer. This simplifies serializing a struct
or enum that contains an external type that doesn't implement
`serde::Serialize`. This expression is passed a variable
`serializer` that needs to be used to serialize the expression.
This allows end users to use an arbitrary expression to decide whether
or not to serialize some field. This expression has access to all the
fields in the struct, but none of the internal state of the Serialize
implementation. For structs, serde implements this by creating a
temporary trait and implementing the struct for it. For struct variants,
the fields are copied by reference into a temporary struct first
before implementing the temporary trait.
This also fixes a bug where the serde_codegen wasn't making calls to
Serializer::serialize_{tuple,struct}_variant{,_elt}.
This feature adds support for the default to be specified to be
some expression (which unfortunately needs to be parsed from
a string) without needing this value to have an implementation
of `Default`, or for a new-type wrapper in order to provide an
alternative implementation. This expression is run in a function,
and therefore has no access to any of the internal state of
the deserializer.