Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

How to deserialize a string representation of boolean in XML

I’m trying to parse xml response containing boolean representation as strings into bool type in a custom structure. A similar question was mentioned here for json files. And I get a runtime error that I suspect is just like the one mentioned here, but I don’t know how I can fix it.

MRE:

[package]
name = "test_range_2"
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.147", features = ["derive"] }
serde-xml-rs = "0.6.0"
// main.rs
use serde::Deserialize;

fn deserialize_bool<'de, D>(deserializer: D) -> Result<bool, D::Error>
where
    D: serde::de::Deserializer<'de>,
{
    let s: &str = serde::de::Deserialize::deserialize(deserializer)?;

    match s {
        "TRUE" => Ok(true),
        "FALSE" => Ok(false),
        _ => Err(serde::de::Error::unknown_variant(s, &["TRUE", "FALSE"])),
    }
}

#[allow(dead_code)]
#[derive(Debug, Deserialize)]
struct Custom {
    #[serde(deserialize_with = "deserialize_bool")]
    tag1: bool,
    #[serde(deserialize_with = "deserialize_bool")]
    tag2: bool,
}

fn main() {
    let xml_raw = r#"
    <?xml version="1.0"?>
    <Custom>
        <tag1>TRUE</tag1>
        <tag2>FALSE</tag2>
    </Custom>
    "#;

    let events = serde_xml_rs::from_str::<Custom>(xml_raw)
        .expect("unable to deserialize xml into Custom struct");

    println!("{:#?}", events);
}

Finished dev [unoptimized + debuginfo] target(s) in 0.02s
     Running `target/debug/test_range_2`
thread 'main' panicked at 'unable to deserialize xml into Custom struct: Custom { field: "invalid type: string \"TRUE\", expected a borrowed string" }', src/main.rs:35:10
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace

Related links:

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

>Solution :

The error message here is useful

"invalid type: string "TRUE", expected a borrowed string"

You are trying to deserialize the string value as a &str instead of a String. This might be weirdness in the serde_xml_rs library but changing it to String lets it run as expected.

fn deserialize_bool<'de, D>(deserializer: D) -> Result<bool, D::Error>
where
    D: serde::de::Deserializer<'de>,
{
    let s: String = serde::de::Deserialize::deserialize(deserializer)?;

    match s.as_str() { // note change here
        "TRUE" => Ok(true),
        "FALSE" => Ok(false),
        _ => Err(serde::de::Error::unknown_variant(&s, &["TRUE", "FALSE"])), // and borrow here
    }
}
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading