From 6f7dda403d85ddc742f9ba406373dd6668324703 Mon Sep 17 00:00:00 2001 From: Xiphoseer Date: Fri, 12 Apr 2024 08:36:18 +0200 Subject: [PATCH 1/2] de: consider local_name only for namespaced tags in structs with $value This updates the "not_in" check that decides whether to pass a new start tag within a struct to a $value field, to only consider the local part of a QName. It now uses the same decode_name function as the QNameDeserializer that is used for keys/fields already to ensure they stay in sync. Using the namespaced name in serde (i.e. `#[serde(rename = "ns1:tag")]`) fails with ``Custom("missing field `ns1:tag`")`` today, so this will not break existing code. Might help with #347 --- src/de/key.rs | 2 +- src/de/map.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/de/key.rs b/src/de/key.rs index 0c003730..d51f129a 100644 --- a/src/de/key.rs +++ b/src/de/key.rs @@ -23,7 +23,7 @@ macro_rules! deserialize_num { /// The method will borrow if encoding is UTF-8 compatible and `name` contains /// only UTF-8 compatible characters (usually only ASCII characters). #[inline] -fn decode_name<'n>(name: QName<'n>, decoder: Decoder) -> Result, DeError> { +pub(super) fn decode_name<'n>(name: QName<'n>, decoder: Decoder) -> Result, DeError> { let local = name.local_name(); Ok(decoder.decode(local.into_inner())?) } diff --git a/src/de/map.rs b/src/de/map.rs index 64ae6a68..8b69ba9a 100644 --- a/src/de/map.rs +++ b/src/de/map.rs @@ -789,7 +789,7 @@ fn not_in( start: &BytesStart, decoder: Decoder, ) -> Result { - let tag = decoder.decode(start.name().into_inner())?; + let tag = super::key::decode_name(start.name(), decoder)?; Ok(fields.iter().all(|&field| field != tag.as_ref())) } From 745278ac52f2be8787db84280e2d7c0ef3be4fcd Mon Sep 17 00:00:00 2001 From: Xiphoseer Date: Fri, 12 Apr 2024 08:53:07 +0200 Subject: [PATCH 2/2] Extend test_not_in --- src/de/map.rs | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/de/map.rs b/src/de/map.rs index 8b69ba9a..05c0b45f 100644 --- a/src/de/map.rs +++ b/src/de/map.rs @@ -1192,4 +1192,18 @@ fn test_not_in() { not_in(&["some", "tag", "included"], &tag, Decoder::utf8()).unwrap(), false ); + + let tag_ns = BytesStart::new("ns1:tag"); + assert_eq!( + not_in(&["no", "such", "tags"], &tag_ns, Decoder::utf8()).unwrap(), + true + ); + assert_eq!( + not_in(&["some", "tag", "included"], &tag_ns, Decoder::utf8()).unwrap(), + false + ); + assert_eq!( + not_in(&["some", "namespace", "ns1:tag"], &tag_ns, Decoder::utf8()).unwrap(), + true + ); }