Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feature serialization: #[serde(flatten)] does not work for different types #286

Closed
jfrimmel opened this issue May 16, 2021 · 1 comment
Closed
Labels
serde Issues related to mapping from Rust types to XML wontfix

Comments

@jfrimmel
Copy link

jfrimmel commented May 16, 2021

Hello,
I encountered an unexpected behavior when using #[serde(flatten)] with this crate. See the example below.

Reproduction

Cargo.toml:

[package]
name = "valgrind-xml"
version = "0.0.0"
edition = "2018"

[dependencies]
quick-xml = { version="0.22", features=["serialize"] }
serde = { version="1", features=["derive"] }
serde_json = "1"

src/main.rs:

use serde::Deserialize;

#[derive(Debug, Deserialize)]
struct S {
    name: String,
    #[serde(flatten)]
    resource: Resource,
}

#[derive(Debug, Deserialize)]
struct Resource {
    a: i32,
    b: u64,
}

// should have the same behavior as `S`, but everything is inlined
#[derive(Debug, Deserialize)]
struct S2 {
    name: String,
    a: i32,
    b: u64,    
}

fn main() {
    let r: Result<S, _> = quick_xml::de::from_str(r#"<root name="omg" a="-1" b="42"/>"#); // doesn't work
    dbg!(r);
    let s: S2 = quick_xml::de::from_str(r#"<root name="omg" a="-1" b="42"/>"#).unwrap(); // works
    dbg!(s);

    // serde_json as reference:
    let s: S = serde_json::de::from_str(r#"{ "name": "omg", "a": -1, "b": 42 }"#).unwrap(); // works
    dbg!(s);
    let s: S2 = serde_json::de::from_str(r#"{ "name": "omg", "a": -1, "b": 42 }"#).unwrap(); // works
    dbg!(s);
}

Output of cargo run:

[src/main.rs:25] r = Err(
    Custom(
        "invalid type: map, expected i32",
    ),
)
[src/main.rs:27] s = S2 {
    name: "omg",
    a: -1,
    b: 42,
}
[src/main.rs:29] s = S {
    name: "omg",
    resource: Resource {
        a: -1,
        b: 42,
    },
}
[src/main.rs:31] s = S2 {
    name: "omg",
    a: -1,
    b: 42,
}
@Mingun
Copy link
Collaborator

Mingun commented May 21, 2022

#[serde(flatten)] is very dependent on the ability of the deserializer to report correct types, but XML deserializer has only two types under the hood: Map and String.

This is impossible to fix from the deserializer side, the fix of serde-rs/serde#1183 is required.

For now avoid using #[serde(flatten)] for types that you want to deserialize from XML.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
serde Issues related to mapping from Rust types to XML wontfix
Projects
None yet
Development

No branches or pull requests

2 participants