serde
serde copied to clipboard
Tag enums differently for serialization and deserialization
It might be a rare usecase and I have workaround for it, but it would be nice if we could settag
container attribute separatly for serialization and deserialization.
To simplify the request, here is a json i would like to deserialize into an enum:
{"struct_type":"A","data":10}
and here is the json that i would like to serialize with the same enum
{"structType":"A","data":10}
and here is my enum definition works only for deserialization:
#[derive(Deserialize, Serialize)]
pub struct A {
pub data: u8,
}
#[derive(Deserialize)]
#[serde(tag = "struct_type")]
pub enum AB {
A(A),
}
my workaround is to write a custom serializater, something like this:
impl Serialize for AB {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
#[derive(Serialize)]
struct EnumTagged<T> {
#[serde(rename = "structType")]
struct_type: String,
#[serde(flatten)]
base: T,
}
match self {
AB::A(field) => {
let e = EnumTagged {
struct_type: "A".into(),
base: field,
};
e.serialize(serializer)
}
}
}
}
My suggestion is to have a specific tag for each of serialization and deserialization.
#[derive(Serialize, Deserialize)]
#[serde(tag(serialize= "struct_type", deserialize="structType"))]
pub enum AB {
A(A),
}