serde-xml-rs
serde-xml-rs copied to clipboard
Add convenience function for parsing common forms of booleans
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?
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))),
}
}
@oli-obk Should this work with the next version.
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.
I though of this test https://github.com/RReverser/serde-xml-rs/blob/master/tests/migrated.rs#L342-L349
Huh? How is that test passing?
https://github.com/RReverser/serde-xml-rs/blob/master/src/de/mod.rs#L230
So it works as a root element but not a field?
Something like <test bla="true"></test>
should also work, but <test bla></test>
shouldn't work currently
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.
@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