Open MoSal opened 3 years ago
I hit this error as well. I added a test case (de::tests::enum_::internally_tagged::collection_struct::attributes
) in the vec-invariant branch on my fork.
It fails with:
---- de::tests::enum_::internally_tagged::collection_struct::attributes stdout ----
thread 'de::tests::enum_::internally_tagged::collection_struct::attributes' panicked at 'called `Result::unwrap()` on an `Err` value: Custom("invalid type: map, expected a sequence")', src/de/mod.rs:1184:26
I correctly understand, that #387 addresses those problems? If not, please try to reduce your example and turn it into the Rust testcase
I have 0.36.1 and I'm still hitting this error. I have this example:
use serde_derive::Deserialize;
#[test]
fn show_bug() {
let xml = r###"
<?xml version='1.0' encoding='UTF-8'?>
<Root>
<Entry type="Foo">
<Datum value="asdf"/>
</Entry>
<Entry type="Bar">
<Datum value="qwer"/>
<Datum value="zxcv"/>
</Entry>
</Root>
"###;
#[derive(Debug, Deserialize)]
struct Root {
#[serde(rename = "Entry")]
entries: Vec<Entry>,
}
#[derive(Debug, Deserialize)]
#[serde(tag = "@type")]
enum Entry {
Foo {
#[serde(rename = "Datum")]
datum: Datum,
},
Bar {
#[serde(rename = "Datum")]
data: Vec<Datum>
}
}
#[derive(Debug, Deserialize)]
struct Datum {
#[serde(rename = "@value")]
value: String,
}
let root: Root = quick_xml::de::from_str(xml).unwrap();
}
which fails with invalid type: map, expected a sequence
@albx79, this is because bufferisation step that internally tagged enums introduces. During bufferisation content of
<Entry type="Bar">
<Datum value="qwer"/>
<Datum value="zxcv"/>
</Entry>
read into private serde's type Content
. Because it is designed to represent any data, it requests deserialization using deserialize_any
. However, in XML model only two types exists which are a string and a map. When deserialize_any
is requested, that model is returned, in that case it would be:
Map {
@type = String(Bar),
Datum = Map {
@value = String(qwer),
},
Datum = Map {
@value = String(zxcv),
},
}
It is stored buffered as Content::Map
which can respond only to deserialize_map
requests by calling Visitor::visit_map
:
https://github.com/serde-rs/serde/blob/e08c5de5dd62571a5687f77d99609f9d9e60784e/serde/src/private/de.rs#L1155
However, we try to deserialize a data
field from Content::Map
which is of type Vec<_>
which requests deserialize_seq
. Content::Map
in that case returns an error "invalid type: map, expected a sequence":
https://github.com/serde-rs/serde/blob/e08c5de5dd62571a5687f77d99609f9d9e60784e/serde/src/private/de.rs#L1368-L1376.
This situation could be improved in two ways:
Content
would have a Multimap
variant which both can answer to deserialize_map
and deserialize_seq
requests and provide a way to fill that variant. I'm not sure, that this will be generic solution, because XML's unique situation is in that that map key (name of tag, i.e. Datum
) is a part of map value (the whole <Datum>...</Datum>
)
Example with tagged and untagged enums showing different errors. The tagged error seems to point to the source of the issue.