Open
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