-
Notifications
You must be signed in to change notification settings - Fork 260
Open
Labels
bughelp wantedserdeIssues related to mapping from Rust types to XMLIssues related to mapping from Rust types to XML
Description
Found in https://stackoverflow.com/questions/67932584/deserializing-recursive-xml-using-serde-in-rust
Currently recursively defined enums using newtype variants for recursion lead to stack overflow error:
#[test]
fn recursive() {
#[derive(Debug, Deserialize, PartialEq)]
#[serde(rename_all = "camelCase")]
enum MathNode {
Apply(Vec<MathNode>),
Ci(Vec<MathNode>),
#[serde(rename = "$text")]
Text(String),
#[serde(rename = "math")]
Root(Vec<MathNode>),
}
let test = r#"
<math>
<apply>
<ci type="integer">5</ci>
</apply>
</math>"#;
assert_eq!(
from_str::<MathNode>(test).unwrap(),
MathNode::Root(vec![MathNode::Apply(vec![MathNode::Ci(vec![
MathNode::Text("5".into())
])])])
);
}
However, if change newtype variant to the struct variant with one $value
field, everything works:
#[test]
fn recursive() {
#[derive(Debug, Deserialize, PartialEq)]
#[serde(rename_all = "camelCase")]
enum MathNode {
Apply {
#[serde(rename = "$value")]
value: Vec<MathNode>,
},
Ci {
#[serde(rename = "$value")]
value: Vec<MathNode>,
},
#[serde(rename = "$text")]
Text(String),
#[serde(rename = "math")]
Root {
#[serde(rename = "$value")]
value: Vec<MathNode>,
},
}
let test = r#"
<math>
<apply>
<ci type="integer">5</ci>
</apply>
</math>"#;
assert_eq!(
from_str::<MathNode>(test).unwrap(),
MathNode::Root {
value: vec![MathNode::Apply {
value: vec![MathNode::Ci {
value: vec![MathNode::Text("5".into())]
}],
}],
}
);
}
It seems worth to implement newtype variant deserialization like such structs
Metadata
Metadata
Assignees
Labels
bughelp wantedserdeIssues related to mapping from Rust types to XMLIssues related to mapping from Rust types to XML