Skip to content

Use $value and $unflatten together #430

Closed
@tyilo

Description

@tyilo

I have some XML that looks like:

<root>
  <state>B</state>
</root>

which I would like to represent in rust as:

enum State {
  A,
  B,
  C,
}

struct Root {
  state: State,
}

I have tried combining $unflatten and $value to make this happen, but it doesn't seem to work:

Cargo.toml:

[package]
name = "quick-xml-test"
version = "0.1.0"
edition = "2021"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
serde = { version = "1.0.139", features = ["derive"] }
quick-xml = { version = "0.23.0", features = ["serialize" ] }

src/main.rs:

mod working {
    use serde::{Deserialize, Serialize};

    #[derive(Debug, Deserialize, Serialize)]
    enum State {
        A,
        B,
        C,
    }

    #[derive(Debug, Deserialize, Serialize)]
    struct StateOuter {
        #[serde(rename = "$value")]
        state: State,
    }

    #[derive(Debug, Deserialize, Serialize)]
    pub struct Root {
        state: StateOuter,
    }
}

mod not_working {
    use serde::{Deserialize, Serialize};

    #[derive(Debug, Deserialize, Serialize)]
    #[serde(rename = "$value")]
    enum State {
        A,
        B,
        C,
    }

    #[derive(Debug, Deserialize, Serialize)]
    pub struct Root {
        #[serde(rename = "$unflatten=state")]
        state: State,
    }
}

fn main() {
    let xml = "<root><state>B</state></root>";
    println!("Deserialized (working): {:?}", quick_xml::de::from_str::<working::Root>(&xml));
    println!("Deserialized (not working): {:?}", quick_xml::de::from_str::<not_working::Root>(&xml));
}

Output:

Deserialized (working): Ok(Root { state: StateOuter { state: B } })
Deserialized (not working): Err(Custom("unknown variant `state`, expected one of `A`, `B`, `C`"))

Is it possible to do without introducing the extra StateOuter struct?

Metadata

Metadata

Assignees

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