serde-xml-rs icon indicating copy to clipboard operation
serde-xml-rs copied to clipboard

Problem with 'untagged'

Open VilNeo opened this issue 4 years ago • 2 comments

Hello,

I try to read an element list via an untagged enum. Unfortunately, I end up in the error "Custom { field: "data did not match any variant of untagged enum Foo" }" everytime. Are untagged enums supported by serde-xml-rs? What am I doing wrong here? Here is an example running into the issue:

use serde_derive::Deserialize;

#[derive(Deserialize)]
#[serde(untagged)]
enum Foo {
    Bar { bar: String },
    Baz { baz: u32 },
}

#[derive(Deserialize)]
struct Stuff {
    foo: Vec<Foo>,
}

fn main() {
    let xml_string = "<?xml version=\"1.0\" encoding=\"utf-8\" standalone=\"no\"?>\
<stuff>\
    <foo>\
        <bar>one</bar>\
    </foo>\
    <foo>\
        <baz>1</baz>\
    </foo>\
</stuff>";
    let _result: Stuff = serde_xml_rs::from_str(xml_string).expect("Parse error");
}

Best regards Alex

VilNeo avatar May 30 '20 08:05 VilNeo

I just run into the same thing in my project: https://github.com/RReverser/serde-xml-rs/commit/d0ba73cce9320fc491c3d4a3e7dbeffd2ef99cf5

I'd expect this to work:

#[test]
fn struct_with_flattened_untagged_enum() {
    init_logger();

    #[derive(Debug, Deserialize, PartialEq)]
    #[serde(untagged)]
    enum Enum {
        A { field_a: i32 },
        B { field_b: i32 },
    }

    #[derive(Debug, Deserialize, PartialEq)]
    struct Struct {
        common_int: i32,
        #[serde(flatten)]
        the_enum: Enum,
    }

    let s = r##"
        <struct>
          <common_int>123</common_int>
          <field_a>456</field_a>
        </struct>
    "##;

    let actual: Struct = from_str(s).unwrap();

    assert_eq!(
        actual,
        Struct {
            common_int: 123,
            the_enum: Enum::A { field_a: 456 },
        }
    );
}

#[test]
fn struct_with_flattened_internally_tagged_enum() {
    init_logger();

    #[derive(Debug, Deserialize, PartialEq)]
    #[serde(tag = "which")]
    enum Enum {
        A { field_a: i32 },
        B { field_b: i32 },
    }

    #[derive(Debug, Deserialize, PartialEq)]
    struct Struct {
        common_int: i32,
        #[serde(flatten)]
        the_enum: Enum,
    }

    let s = r##"
        <struct>
          <common_int>123</common_int>
          <which>A</which>
          <field_a>456</field_a>
        </struct>
    "##;

    let actual: Struct = from_str(s).unwrap();

    assert_eq!(
        actual,
        Struct {
            common_int: 123,
            the_enum: Enum::A { field_a: 456 },
        }
    );
}

But I get:

thread 'struct_with_flattened_untagged_enum' panicked at 'called `Result::unwrap()` on an `Err` value: Custom { field: "data did not match any variant of untagged enum Enum" }', tests/test.rs:193:38
thread 'struct_with_flattened_internally_tagged_enum' panicked at 'called `Result::unwrap()` on an `Err` value: Custom { field: "invalid type: map, expected variant identifier" }', tests/test.rs:230:38

agentydragon avatar Feb 16 '21 22:02 agentydragon

same, I believe this is related to https://github.com/serde-rs/serde/issues/1183

Sharpiro avatar Jun 01 '23 19:06 Sharpiro