When a struct uses #[serde(tag)] and also internally-tagged typetag, currently when serializing, the tag appears twice in the resulting JSON - one time it is added by typetag and one time by serde.
This MR makes InternallyTaggedSerializer output just a single tag entry. It does so by adding a check to serialize_field(), that if the key is the tag, it doesn't continue to serialize the field. In debug mode, it will also assert that the value is the same as was already written.
I needed this to implement https://github.com/DeterminateSystems/nix-installer/issues/1062 - I wanted to have a tag field for all "Action" entries in the json, even though some were dyn Action and some were plain structs which implement Action. Without this change, the tag entries would appear twice, so the JSON would be broken. To make it clearer, here's the change in the JSON that the mentioned issue suggests:
When a struct uses
#[serde(tag)]
and also internally-tagged typetag, currently when serializing, the tag appears twice in the resulting JSON - one time it is added by typetag and one time by serde.This MR makes InternallyTaggedSerializer output just a single tag entry. It does so by adding a check to serialize_field(), that if the key is the tag, it doesn't continue to serialize the field. In debug mode, it will also assert that the value is the same as was already written.
I needed this to implement https://github.com/DeterminateSystems/nix-installer/issues/1062 - I wanted to have a tag field for all "Action" entries in the json, even though some were
dyn Action
and some were plain structs which implementAction
. Without this change, the tag entries would appear twice, so the JSON would be broken. To make it clearer, here's the change in the JSON that the mentioned issue suggests:What do you think?
Thanks! Noam