Skip to content

Commit 2ec4873

Browse files
authored
fix(value): Fixed deserialize_seq on most XML value types. (#124)
* fix(value): Fixed `deserialize_seq` on most value types. * Simplified test.
1 parent fe3f75e commit 2ec4873

File tree

5 files changed

+92
-53
lines changed

5 files changed

+92
-53
lines changed

xmlity-quick-xml/tests/features.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,5 @@ pub mod groups;
33
pub mod other;
44
pub mod text;
55
pub mod utils;
6+
pub mod value;
67
pub mod with;
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
pub mod linkbase_ref_items {
2+
#[derive(
3+
Debug, ::xmlity::SerializationGroup, ::xmlity::DeserializationGroup, PartialEq, Clone,
4+
)]
5+
pub struct LinkbaseRef {}
6+
}
7+
#[derive(Debug, ::xmlity::Serialize, ::xmlity::Deserialize, PartialEq, Clone)]
8+
pub enum LinkbaseRef {
9+
#[xelement(
10+
name = "linkbaseRef",
11+
namespace = "http://www.xbrl.org/2003/linkbase",
12+
allow_unknown_attributes = "any"
13+
)]
14+
LinkbaseRef(#[xgroup] linkbase_ref_items::LinkbaseRef),
15+
}
16+
17+
const LINKBASE_REF: &str = r###"
18+
<link:linkbaseRef
19+
xmlns:link="http://www.xbrl.org/2003/linkbase" />
20+
"###;
21+
22+
#[test]
23+
fn linkbase_ref() {
24+
let direct: LinkbaseRef =
25+
xmlity_quick_xml::from_str(LINKBASE_REF.trim()).expect("Failed to parse linkbaseRef XML");
26+
27+
let element: xmlity::value::XmlValue =
28+
xmlity_quick_xml::from_str(LINKBASE_REF.trim()).expect("Failed to parse linkbaseRef XML");
29+
30+
let indirect: LinkbaseRef =
31+
xmlity::Deserialize::deserialize(&element).expect("Failed to deserialize linkbaseRef XML");
32+
33+
assert_eq!(direct, indirect);
34+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
pub mod indirect_direct_equal;

xmlity/src/types/common.rs

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,56 @@ impl<T: SerializationGroup> SerializationGroup for Option<T> {
159159
}
160160
}
161161

162+
impl<'de, D> de::SeqAccess<'de> for Option<&'de D>
163+
where
164+
&'de D: de::Deserializer<'de>,
165+
{
166+
type Error = <&'de D as de::Deserializer<'de>>::Error;
167+
168+
type SubAccess<'g>
169+
= Self
170+
where
171+
Self: 'g;
172+
173+
fn next_element<T>(&mut self) -> Result<Option<T>, Self::Error>
174+
where
175+
T: Deserialize<'de>,
176+
{
177+
let Some(text) = self.take() else {
178+
return Ok(None);
179+
};
180+
181+
match T::deserialize(text) {
182+
Ok(value) => Ok(Some(value)),
183+
Err(_) => {
184+
*self = Some(text);
185+
Ok(None)
186+
}
187+
}
188+
}
189+
190+
fn next_element_seq<T>(&mut self) -> Result<Option<T>, Self::Error>
191+
where
192+
T: Deserialize<'de>,
193+
{
194+
let Some(text) = self.take() else {
195+
return Ok(None);
196+
};
197+
198+
match T::deserialize_seq(text) {
199+
Ok(value) => Ok(Some(value)),
200+
Err(_) => {
201+
*self = Some(text);
202+
Ok(None)
203+
}
204+
}
205+
}
206+
207+
fn sub_access(&mut self) -> Result<Self::SubAccess<'_>, Self::Error> {
208+
Ok(*self)
209+
}
210+
}
211+
162212
impl<T: Serialize> Serialize for Box<T> {
163213
fn serialize<S: crate::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
164214
(**self).serialize(serializer)

xmlity/src/value/deserializer.rs

Lines changed: 6 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ impl<'de> Deserializer<'de> for &'de XmlCData {
9696
where
9797
V: Visitor<'de>,
9898
{
99-
self.deserialize_any(visitor)
99+
visitor.visit_seq(Some(self))
100100
}
101101
}
102102

@@ -174,7 +174,7 @@ impl<'de> Deserializer<'de> for &'de XmlElement {
174174
where
175175
V: Visitor<'de>,
176176
{
177-
self.deserialize_any(visitor)
177+
visitor.visit_seq(Some(self))
178178
}
179179
}
180180

@@ -277,7 +277,7 @@ impl<'de> Deserializer<'de> for &'de XmlProcessingInstruction {
277277
where
278278
V: Visitor<'de>,
279279
{
280-
self.deserialize_any(visitor)
280+
visitor.visit_seq(Some(self))
281281
}
282282
}
283283

@@ -294,7 +294,7 @@ impl<'de> Deserializer<'de> for &'de XmlDecl {
294294
where
295295
V: Visitor<'de>,
296296
{
297-
self.deserialize_any(visitor)
297+
visitor.visit_seq(Some(self))
298298
}
299299
}
300300

@@ -310,7 +310,7 @@ impl<'de> Deserializer<'de> for &'de XmlComment {
310310
where
311311
V: Visitor<'de>,
312312
{
313-
self.deserialize_any(visitor)
313+
visitor.visit_seq(Some(self))
314314
}
315315
}
316316

@@ -328,7 +328,7 @@ impl<'de> Deserializer<'de> for &'de XmlDoctype {
328328
where
329329
V: Visitor<'de>,
330330
{
331-
self.deserialize_any(visitor)
331+
visitor.visit_seq(Some(self))
332332
}
333333
}
334334

@@ -591,50 +591,3 @@ impl<'de> de::XmlText<'de> for &'de XmlText {
591591

592592
fn context(&self) -> Self::DeserializeContext<'_> {}
593593
}
594-
595-
impl<'de> de::SeqAccess<'de> for Option<&'de XmlText> {
596-
type Error = XmlValueDeserializerError;
597-
598-
type SubAccess<'g>
599-
= Self
600-
where
601-
Self: 'g;
602-
603-
fn next_element<T>(&mut self) -> Result<Option<T>, Self::Error>
604-
where
605-
T: Deserialize<'de>,
606-
{
607-
let Some(text) = self.take() else {
608-
return Ok(None);
609-
};
610-
611-
match T::deserialize(text) {
612-
Ok(value) => Ok(Some(value)),
613-
Err(_) => {
614-
*self = Some(text);
615-
Ok(None)
616-
}
617-
}
618-
}
619-
620-
fn next_element_seq<T>(&mut self) -> Result<Option<T>, Self::Error>
621-
where
622-
T: Deserialize<'de>,
623-
{
624-
let Some(text) = self.take() else {
625-
return Ok(None);
626-
};
627-
628-
match T::deserialize_seq(text) {
629-
Ok(value) => Ok(Some(value)),
630-
Err(_) => {
631-
*self = Some(text);
632-
Ok(None)
633-
}
634-
}
635-
}
636-
637-
fn sub_access(&mut self) -> Result<Self::SubAccess<'_>, Self::Error> {
638-
Ok(*self)
639-
}
640-
}

0 commit comments

Comments
 (0)