really fix scalar enum namespace handling

It is actually important to consider the field name when provided,
otherwise we can incorrectly match fields with different names!
This commit is contained in:
Wez Furlong 2024-05-24 15:57:44 -07:00 committed by Dirkjan Ochtman
parent 2156e100ee
commit 775bad82a4
2 changed files with 54 additions and 2 deletions

View File

@ -77,7 +77,13 @@ fn deserialize_scalar_enum(
impl #impl_generics FromXml<'xml> for #ident #ty_generics #where_clause {
#[inline]
fn matches(id: ::instant_xml::Id<'_>, field: Option<::instant_xml::Id<'_>>) -> bool {
id == ::instant_xml::Id { ns: #default_namespace, name: id.name }
id == ::instant_xml::Id {
ns: #default_namespace,
name: match field {
Some(fid) => fid.name,
None => id.name,
},
}
}
fn deserialize<'cx>(
@ -99,7 +105,7 @@ fn deserialize_scalar_enum(
let value = match cow_str.as_ref() {
#variants
_ => return Err(Error::UnexpectedValue(
format!("enum variant not found for '{}'", cow_str),
format!("enum variant not found for '{}' in field {}", cow_str, field),
)),
};

View File

@ -42,3 +42,49 @@ fn scalar_enum_ns() {
assert_eq!(xml, to_string(&v).unwrap());
assert_eq!(v, from_str(xml).unwrap());
}
const DIDL: &str = "DIDL";
const UPNP: &str = "UPNP";
const DC: &str = "DC";
#[derive(Debug, FromXml, PartialEq, ToXml)]
#[xml(rename = "DIDL-Lite", ns(DIDL, dc = DC, upnp = UPNP))]
struct DidlLite {
item: Vec<UpnpItem>,
}
#[derive(Debug, FromXml, PartialEq, ToXml)]
#[xml(rename = "item", ns(DIDL))]
struct UpnpItem {
class: Option<ObjectClass>,
}
#[derive(Debug, Clone, PartialEq, FromXml, ToXml)]
#[xml(rename = "class", scalar, ns(UPNP, upnp = UPNP))]
enum ObjectClass {
#[xml(rename = "object.item.audioItem.musicTrack")]
MusicTrack,
#[xml(rename = "object.item.audioItem.audioBroadcast")]
AudioBroadcast,
#[xml(rename = "object.container.playlistContainer")]
PlayList,
}
#[test]
fn scalar_enum_ns_match() {
let v = DidlLite {
item: vec![UpnpItem {
class: Some(ObjectClass::AudioBroadcast),
}],
};
// Keep the `upnp::mimeType` element after `upnp::class` to ensure that
// we tickle a `DuplicateValue` error if we don't match correctly.
let xml = r#"<DIDL-Lite xmlns="DIDL" xmlns:upnp="UPNP" xmlns:dc="DC" xmlns:dlna="DLNA">
<item>
<upnp:class>object.item.audioItem.audioBroadcast</upnp:class>
<upnp:mimeType>audio/flac</upnp:mimeType>
</item>
</DIDL-Lite>"#;
assert_eq!(v, from_str(xml).unwrap());
}