I'm writing a program that downloads files in a variety of formats, with a variety of numbers of levels of indirection. My config file is in YAML format and I'm using serde to parse it. The configuration file contains
file1:
format1_url: "yada yada"
key_to_extract: "blah blah"
file2:
format2_url: "asdfghjkl"
file3: "skip"
file4:
format3_url: "http://example.com"
My enum looks like:
#[derive(Deserialize)]
#[serde(untagged)]
enum ConfigLine {
Format1{format1_url: String, key_to_extract: String},
Format2{format2_url: String},
Format3{format3_url: String},
Skip,
}
Can I do this with a single enum? Is there a #[serde(...)] tag that I can put on Skip to accomplish this? Or would I be better off splitting it into two enums and manually implementing Deserialize on the outer one, like so:
enum ConfigLine {
Inner(ConfigLineInner),
Skip,
}
#[derive(Deserialize)]
enum ConfigLineInner {
...
}
struct ConfigLineVisitor;
impl<'de> Visitor<'de> for ConfigLineVisitor {
fn visit_str(self, s: &str) -> Result<...> {
if s=="skip" {
Ok(Skip)
} else {
Err(E::custom("expecting config line or \"skip\""))
}
}
fn visit_map(self, map: MapAccess<'de>) {
// somehow connect `map` to ConfigLineInner's derived Deserialize implementation.
// maybe using a fake deserializer?
}
}