RReverser / serde-xml-rs

xml-rs based deserializer for Serde (compatible with 1.0+)
https://crates.io/crates/serde-xml-rs
MIT License
270 stars 90 forks source link

Add convenience function for parsing common forms of booleans #44

Open mdashti opened 7 years ago

mdashti commented 7 years ago

Hi all,

I have the following (minimized) program:

#[macro_use]
extern crate serde_derive;
extern crate serde;
extern crate serde_xml_rs as serde_xml;

#[derive(Deserialize, Debug)]
pub struct ListBucketResult {
    #[serde(rename = "IsTruncated")]
    pub is_truncated: bool
}

fn main() {
    let result_string = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<ListBucketResult xmlns=\"http://s3.amazonaws.com/doc/2006-03-01/\"><Name>relationalai</Name><Prefix>/</Prefix><KeyCount>0</KeyCount><MaxKeys>1000</MaxKeys><IsTruncated>false</IsTruncated></ListBucketResult>";
    let deserialized: ListBucketResult = serde_xml::deserialize(result_string.as_bytes()).expect("Parse error!");
}

And the result of running it is:

thread 'main' panicked at 'Parse error!: invalid type: string "false", expected a boolean', src/libcore/result.rs:860:4
stack backtrace:
   0:        0x10d695833 - std::sys::imp::backtrace::tracing::imp::unwind_backtrace::h5d6b821bcccc8af3
   1:        0x10d69681a - std::panicking::default_hook::{{closure}}::haca53f8b96e15b81
   2:        0x10d6964e2 - std::panicking::default_hook::h0029f59c1ec97ffc
   3:        0x10d698a22 - std::panicking::rust_panic_with_hook::hb8eae939c3fcaf9c
   4:        0x10d698884 - std::panicking::begin_panic_new::h3c5f9a0be81106be
   5:        0x10d6987d2 - std::panicking::begin_panic_fmt::hf585b6224c51a06c
   6:        0x10d69873a - rust_begin_unwind
   7:        0x10d6bffc3 - core::panicking::panic_fmt::h13ed235e8f32b1d5
   8:        0x10d636f7e - core::result::unwrap_failed::he22d59ef245624e4
   9:        0x10d62f274 - <core::result::Result<T, E>>::expect::hbd704600f0f822af
  10:        0x10d644522 - test_proj::main::ha13d119a4874b1d9
  11:        0x10d69982c - __rust_maybe_catch_panic
  12:        0x10d698d18 - std::rt::lang_start::heed3cc6f59fb65ca
  13:        0x10d645199 - main

I am using rustc 1.20.0 (f3d6973f4 2017-08-27) and my sample project is in test_proj.zip.

Can anyone help me to solve the issue?

oli-obk commented 7 years ago

This is expected. You should use #[serde(deserialize_with=foo)] and

fn foo<'de, D>(d: D) -> Result<T, D::Error> where D: Deserializer<'de> {
    let s = String::deserialize(d)?;
    match &s[..] {
        "true" => Ok(true),
        "false" => Ok(false),
        other => Err(D::Error::custom(format!("got {}, but expected `true` or `false`", other))),
    }
}
farodin91 commented 7 years ago

@oli-obk Should this work with the next version.

oli-obk commented 7 years ago

No. This is a can of worms that we do not want to open (see https://github.com/RReverser/serde-xml-rs/pull/18). We can offer the function foo as a convenience function though, since this seems to be a common issue.

farodin91 commented 7 years ago

I though of this test https://github.com/RReverser/serde-xml-rs/blob/master/tests/migrated.rs#L342-L349

oli-obk commented 7 years ago

Huh? How is that test passing?

farodin91 commented 7 years ago

https://github.com/RReverser/serde-xml-rs/blob/master/src/de/mod.rs#L230

oli-obk commented 7 years ago

So it works as a root element but not a field?

farodin91 commented 7 years ago

Something like <test bla="true"></test> should also work, but <test bla></test> shouldn't work currently

mdashti commented 7 years ago

The rust-s3 project was apparently working fine before and could parse this xml:

<ListBucketResult
    xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
    <Name>RelationalAI</Name>
    <Prefix>/</Prefix>
    <KeyCount>0</KeyCount>
    <MaxKeys>1000</MaxKeys>
    <IsTruncated>true</IsTruncated>
</ListBucketResult>

But, it does not work now, and it might be because of some recent changes in your codebase.

RReverser commented 7 years ago

@mdashti serde-xml-rs definitely didn't support that format, it's rather because it switched from serde-xml to serde-xml-rs in rust-s3 in https://github.com/durch/rust-s3/commit/2f684e28b8750fb9b5ea44572c95935d918d73f7