Skip to content

Deserialization of enum variant which recursively refers to itself failed with stackoverflow #819

Open
@Mingun

Description

@Mingun

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

No one assigned

    Labels

    bughelp wantedserdeIssues related to mapping from Rust types to XML

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions