-
Couldn't load subscription status.
- Fork 266
Description
Suppose I have the following prototype XML:
<container>
<a />
<b kind="first" />
<b kind="second">This child has <italic>mixed</italic> <bold>content</bold>, so I <shout>DO</shout> need `$value` to parse properly.</b>
</container>The natural way to represent this using serde would be to use an externally tagged enum to distinguish between <a> and <b> tags, and then a secondary internally tagged enum for distinguishing <b> tags in terms of attribute @kind, as follows:
#[derive(Serialize, Deserialize)]
#[serde(rename = "container")]
struct Container {
#[serde(rename = "$value")]
pub items: Vec<Child>,
}
#[derive(Serialize, Deserialize)]
#[serde(rename_all = "lowercase")]
enum Child {
A(()),
B(ChildB),
}
#[derive(Serialize, Deserialize)]
#[serde(rename_all = "lowercase", tag = "@kind")]
enum ChildB {
First(()),
Second(ChildBSecond),
}
#[derive(Serialize, Deserialize)]
struct ChildBSecond {
#[serde(rename = "$value")]
pub items: Vec<ChildBItem>,
}
#[derive(Serialize, Deserialize)]
#[serde(rename_all = "lowercase")]
enum ChildBItem {
#[serde(rename = "$text")]
Text(String),
Italic(String),
Bold(String),
Shout(String),
}However, attempting to parse the given XML input:
let container: Container = quick_xml::de::from_str(TEXT).unwrap();with this structure using quick_xml::de deserializer panics with the following message:
called `Result::unwrap()` on an `Err` value: Custom("missing field `$value`")`
The problem seems to be from my debugging that during deserialization of ChildB, that the field $value is consumed and converted into its constituent parts, and so when it comes to ChildBItem's turn, the field is missing, but the deserialized key-value sequence is present.
Now, I'm not sure if this is a known issue, but I've run into this problem while attempting to deserialize the Vulkan XML registry file, which frequently uses this XML structures to represent various types and enums. I tried various methods to circumvent this issue, but I couldn't find an elegant method, so now I'm rolling out my own deserializer.
It would be to my own convenience if anyone here knows how to fix this, or if a fix to this is possible within the library itself.
EDIT: added clarification as to what the source of the problem might be.
EDIT 2: removed extraneous tabs from the code.