I'm working with Rust to deserialize YAML data into an enum, but I want to use the key of a map in the YAML file as the tag which identifies the enum variant. Here's the relevant code:
#[derive(Debug, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum Sink {
Csv(CsvSink),
Json(JsonSink),
}
#[derive(Debug, Deserialize)]
pub struct CsvSink {
file_path: String,
delimiter: char,
append: bool
}
Currently, I can deserialize from this YAML file:
!csv
file_path: "tmp/output-data.csv"
delimiter: ,
append: true
However, I want the YAML to look like this (i.e.:
csv:
file_path: "tmp/output-data.csv"
delimiter: ,
append: true
How can I adjust my code to use the key in the yaml as the tag which determines the enum variant?
I have tried using different serde container attributes but have not found the right option
One of the breaking change in serde_yaml
v0.9.0 is (de)serializing enum variants as !
tags instead of maps. The old behavior can be restored with serde_yaml::with::singleton_map
, but this requires a wrapper type to apply the #[serde(with)]
attribute to it:
#[derive(Debug, Deserialize)]
#[serde(transparent)]
pub struct Wrapper(#[serde(with = "serde_yaml::with::singleton_map")] pub Sink);
#[derive(Debug, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum Sink {
Csv(CsvSink),
Json(JsonSink),
}
#[derive(Debug, Deserialize)]
pub struct CsvSink {
file_path: String,
delimiter: char,
append: bool,
}