#[test]
fn test_msg_serde2() {
use serde::{Deserialize, Serialize};
#[derive(Serialize, Deserialize, Debug)]
struct WhyAmIaSequence<T>(#[serde(skip)] u8, T);
let msg_inp = WhyAmIaSequence(1, "hello");
let json_out = serde_json::to_string(&msg_inp).unwrap();
println!("json_out: {}", json_out); // json_out: ["hello"]
#[derive(Serialize, Deserialize, Debug)]
struct HoweverIAmNotSequence<T>(T);
let msg_inp = HoweverIAmNotSequence("hello");
let json_out = serde_json::to_string(&msg_inp).unwrap();
println!("json_out: {}", json_out); // json_out: "hello"
}
Looking at macro expansions, it seems like one gets implemented via Serializer::serialize_newtype_struct
and the other via Serializer::serialize_tuple_struct
.
Edit:
I’m not sure of the exact motivations. Maybe they want #[serde(skip)]
to be consistent with alternatives such as skipping only serialization or only deserialization of the field, or skipping conditionally, in which case it’s probably problematic to avoid the sequence for the json representation.
If you want to work around the issue, one option could be to use #[serde(transparent)]
. This is a bit different yet again, as it’s implemented by skipping the struct alltogether and directly calling into the serialization of the single (serialized) field, but at least for JSON serialization, the effect should be the same as the implicit serialize_newtype_struct
approach of the HoweverIAmNotSequence
struct:
#[derive(Serialize, Deserialize, Debug)]
#[serde(transparent)]
struct WhyAmIaSequence<T>(#[serde(skip)] u8, T);
Your first data structure WhyAmIaSequence
is considered to be a tuple struct by Serde's derive macros. This is a syntax thing that doesn't get affect by #[serde(skip)]
. The type HoweverIAmNotSequence
is a tuple struct with a single field, also known as a New type or Unit struct. They are commonly used to implement new functions or traits on a type where orphan rules would not permit. Syn, the parser used by Serde's derives, detects this as Fields::Unit
and judging the intent of the type as a Newtype, Serde delegates to the Serialize
or Deserialize
implementation of the inner type. Whilst with the tuple struct, it interprets it as a fixed length list of differently typed items
Here is an excerpt from the expanded Serialize
implementation of WhyAmIaSequence
:
let mut __serde_state = _serde::Serializer::serialize_tuple_struct(__serializer, "WhyAmIaSequence", 0 + 1)?;
_serde::ser::SerializeTupleStruct::serialize_field(&mut __serde_state, &self.1)?;
_serde::ser::SerializeTupleStruct::end(__serde_state)
And a similar excerpt from HoweverIAmNotSequence
:
_serde::Serializer::serialize_newtype_struct(__serializer, "HoweverIAmNotSequence", &self.0)