You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
When serializing, enumeration payloads can be tagged in four ways:
externally (the default)
internally (#[serde(tag = "type")])
adjacently (#[serde(tag = "t", content = "c")])
un-tagged (#[serde(untagged)])
Internal tagging is particularly useful when you want to version your structures; you can maintain different structs in your code, and in serialized format, each will appear to have a field named "version" (or whatever). E.g.
#[derive(Deserialize,Serialize)]pubstructFirstVersion{// stuff}#[derive(Deserialize,Serialize)]pubstructSecondVersion{// similar but not the same stuff}#[derive(Deserialize,Serialize)]#[serde(tag = "version")]enumVersions{#[serde(name = "v1")]V1(FirstVersion),#[serde(name = "v2")]V1(SecondVersion),}
If I write out V1, it will be something like ((version . "V1") (x . 1) (y . "blah")), but deserialization will fail.
I've debugged the internally tagged case down to the point where I can see Deserializer::deserialize_identifier being invoked (serde-lexpr/serc/value, line 259) on ("version" . "V1"), expect a symbol, and fail. That call is generated by the derive(Deserialize) code, so it seems like the place to change. But it's odd that there doesn't seem to be a natural place to check the "version" tag. Also, serde-json implements deserialize_identifier simply by reading a string-- seems like it, too would be broken here, so I'm still missing something.
The text was updated successfully, but these errors were encountered:
sp1ff
changed the title
Internal tagging of enums not honored
Non-default enum tagging broken
Nov 11, 2021
When serializing, enumeration payloads can be tagged in four ways:
#[serde(tag = "type")]
)#[serde(tag = "t", content = "c")]
)#[serde(untagged)]
)Internal tagging is particularly useful when you want to version your structures; you can maintain different structs in your code, and in serialized format, each will appear to have a field named "version" (or whatever). E.g.
If I write out V1, it will be something like ((version . "V1") (x . 1) (y . "blah")), but deserialization will fail.
Full test case-- click to expand
I've debugged the internally tagged case down to the point where I can see
Deserializer::deserialize_identifier
being invoked (serde-lexpr/serc/value
, line 259) on ("version" . "V1"), expect a symbol, and fail. That call is generated by thederive(Deserialize)
code, so it seems like the place to change. But it's odd that there doesn't seem to be a natural place to check the "version" tag. Also, serde-json implements deserialize_identifier simply by reading a string-- seems like it, too would be broken here, so I'm still missing something.The text was updated successfully, but these errors were encountered: