1use crate::error::{Error, Result};
7use crate::reader::{Attribute, XmlEvent, XmlReader};
8use serde::de::{self, DeserializeSeed, MapAccess, SeqAccess, Visitor};
9use std::borrow::Cow;
10
11pub fn from_str<'de, T>(s: &'de str) -> Result<T>
31where
32 T: de::Deserialize<'de>,
33{
34 let mut de = Deserializer::from_str(s);
35 T::deserialize(&mut de)
36}
37
38pub fn from_bytes<'de, T>(bytes: &'de [u8]) -> Result<T>
40where
41 T: de::Deserialize<'de>,
42{
43 let s = std::str::from_utf8(bytes).map_err(|e| {
44 let offset = e.valid_up_to();
45 let mut line = 1;
46 let mut column = 1;
47 for &b in &bytes[..offset] {
48 if b == b'\n' {
49 line += 1;
50 column = 1;
51 } else if b & 0xC0 != 0x80 {
52 column += 1;
53 }
54 }
55 Error::new(crate::error::ErrorKind::InvalidUtf8)
56 .with_position(crate::error::Position { line, column, offset })
57 })?;
58 from_str(s)
59}
60
61pub struct Deserializer<'de> {
63 reader: XmlReader<'de>,
64 peeked: Option<XmlEvent<'de>>,
66 pending_value: Option<Cow<'de, str>>,
72 start_consumed: bool,
74 is_empty_element: bool,
76 text_key: &'static str,
78 pending_wrapper: bool,
84}
85
86impl<'de> Deserializer<'de> {
87 #[allow(clippy::should_implement_trait)]
89 pub fn from_str(s: &'de str) -> Self {
90 Self {
91 reader: XmlReader::from_str(s),
92 peeked: None,
93 pending_value: None,
94 start_consumed: false,
95 is_empty_element: false,
96 text_key: "$value",
97 pending_wrapper: false,
98 }
99 }
100
101 fn peek_event(&mut self) -> Result<&XmlEvent<'de>> {
103 if self.peeked.is_none() {
104 self.peeked = Some(self.reader.next_event()?);
105 }
106 Ok(self.peeked.as_ref().unwrap())
107 }
108
109 fn next_event(&mut self) -> Result<XmlEvent<'de>> {
111 if let Some(event) = self.peeked.take() {
112 Ok(event)
113 } else {
114 self.reader.next_event()
115 }
116 }
117
118 fn skip_ignorable_events(&mut self) -> Result<()> {
125 loop {
126 match self.peek_event()? {
127 XmlEvent::XmlDecl { .. }
128 | XmlEvent::Comment(_)
129 | XmlEvent::ProcessingInstruction { .. } => {
130 self.next_event()?;
131 }
132 _ => return Ok(()),
133 }
134 }
135 }
136
137 fn read_text_content(&mut self) -> Result<Cow<'de, str>> {
141 let mut content: Option<Cow<'de, str>> = None;
142
143 loop {
144 match self.peek_event()? {
145 XmlEvent::Text(_) | XmlEvent::CData(_) => {
146 let text = match self.next_event()? {
147 XmlEvent::Text(text) | XmlEvent::CData(text) => text,
148 _ => unreachable!(),
149 };
150 content = Some(match content {
151 None => text,
152 Some(existing) => {
153 let mut joined = existing.into_owned();
154 joined.push_str(&text);
155 Cow::Owned(joined)
156 }
157 });
158 }
159 XmlEvent::Comment(_) | XmlEvent::ProcessingInstruction { .. } => {
160 self.next_event()?;
161 }
162 _ => break,
163 }
164 }
165
166 Ok(content.unwrap_or(Cow::Borrowed("")))
167 }
168
169 fn read_element_text(&mut self) -> Result<Cow<'de, str>> {
171 if self.is_empty_element {
172 self.is_empty_element = false;
173 self.start_consumed = false;
174 return Ok(Cow::Borrowed(""));
175 }
176
177 let content = self.read_text_content()?;
178
179 if self.start_consumed {
181 self.start_consumed = false;
182 if let XmlEvent::EndElement { .. } = self.peek_event()? {
183 self.next_event()?;
184 }
185 }
186
187 Ok(content)
188 }
189
190 fn skip_element(&mut self) -> Result<()> {
192 self.drain_to_matching_end()
193 }
194
195 fn drain_to_matching_end(&mut self) -> Result<()> {
202 let mut depth = 0usize;
203 loop {
204 match self.peek_event()? {
205 XmlEvent::StartElement { .. } => {
206 depth += 1;
207 self.next_event()?;
208 }
209 XmlEvent::EndElement { .. } => {
210 self.next_event()?;
211 if depth == 0 {
212 return Ok(());
213 }
214 depth -= 1;
215 }
216 XmlEvent::Eof => {
217 return Err(Error::unexpected_eof().with_position(self.reader.position()))
218 }
219 _ => {
220 self.next_event()?;
221 }
222 }
223 }
224 }
225
226 fn parse_value<T>(&self, s: &str) -> Result<T>
228 where
229 T: std::str::FromStr,
230 T::Err: std::fmt::Display,
231 {
232 s.parse().map_err(|e: T::Err| {
233 Error::invalid_value(e.to_string()).with_position(self.reader.position())
234 })
235 }
236
237 fn get_text_cow(&mut self) -> Result<Cow<'de, str>> {
239 self.pending_wrapper = false;
241 if let Some(value) = self.pending_value.take() {
242 return Ok(value);
243 }
244
245 if self.start_consumed {
247 return self.read_element_text();
248 }
249
250 self.skip_ignorable_events()?;
252 match self.peek_event()? {
253 XmlEvent::StartElement { .. } => {
254 self.next_event()?;
255 self.start_consumed = true;
256 self.is_empty_element = false;
257 self.read_element_text()
258 }
259 XmlEvent::EmptyElement { .. } => {
260 self.next_event()?;
261 Ok(Cow::Borrowed(""))
262 }
263 _ => self.read_text_content(),
264 }
265 }
266
267 fn get_text(&mut self) -> Result<String> {
269 Ok(self.get_text_cow()?.into_owned())
270 }
271}
272
273fn text_key_for(fields: &[&'static str]) -> &'static str {
277 if fields.contains(&"$text") && !fields.contains(&"$value") {
278 "$text"
279 } else {
280 "$value"
281 }
282}
283
284impl<'de> de::Deserializer<'de> for &mut Deserializer<'de> {
285 type Error = Error;
286
287 fn deserialize_any<V>(self, visitor: V) -> Result<V::Value>
288 where
289 V: Visitor<'de>,
290 {
291 if let Some(value) = self.pending_value.take() {
292 return match value {
293 Cow::Borrowed(text) => visitor.visit_borrowed_str(text),
294 Cow::Owned(text) => visitor.visit_string(text),
295 };
296 }
297
298 match self.peek_event()? {
299 XmlEvent::StartElement { .. } | XmlEvent::EmptyElement { .. } => {
300 self.deserialize_map(visitor)
301 }
302 XmlEvent::Text(text) => {
303 let text = text.clone().into_owned();
304 self.next_event()?;
305 visitor.visit_string(text)
306 }
307 XmlEvent::CData(data) => {
308 let data = data.clone().into_owned();
309 self.next_event()?;
310 visitor.visit_string(data)
311 }
312 XmlEvent::EndElement { .. } => visitor.visit_unit(),
313 XmlEvent::Eof => visitor.visit_unit(),
314 _ => {
315 self.next_event()?;
316 self.deserialize_any(visitor)
317 }
318 }
319 }
320
321 fn deserialize_bool<V>(self, visitor: V) -> Result<V::Value>
322 where
323 V: Visitor<'de>,
324 {
325 let text = self.get_text_cow()?;
326 match &*text {
327 "true" | "1" | "yes" => visitor.visit_bool(true),
328 "false" | "0" | "no" => visitor.visit_bool(false),
329 _ => Err(Error::invalid_value(format!("expected boolean, got '{}'", text))
330 .with_position(self.reader.position())),
331 }
332 }
333
334 fn deserialize_i8<V>(self, visitor: V) -> Result<V::Value>
335 where
336 V: Visitor<'de>,
337 {
338 let text = self.get_text_cow()?;
339 visitor.visit_i8(self.parse_value(&text)?)
340 }
341
342 fn deserialize_i16<V>(self, visitor: V) -> Result<V::Value>
343 where
344 V: Visitor<'de>,
345 {
346 let text = self.get_text_cow()?;
347 visitor.visit_i16(self.parse_value(&text)?)
348 }
349
350 fn deserialize_i32<V>(self, visitor: V) -> Result<V::Value>
351 where
352 V: Visitor<'de>,
353 {
354 let text = self.get_text_cow()?;
355 visitor.visit_i32(self.parse_value(&text)?)
356 }
357
358 fn deserialize_i64<V>(self, visitor: V) -> Result<V::Value>
359 where
360 V: Visitor<'de>,
361 {
362 let text = self.get_text_cow()?;
363 visitor.visit_i64(self.parse_value(&text)?)
364 }
365
366 fn deserialize_u8<V>(self, visitor: V) -> Result<V::Value>
367 where
368 V: Visitor<'de>,
369 {
370 let text = self.get_text_cow()?;
371 visitor.visit_u8(self.parse_value(&text)?)
372 }
373
374 fn deserialize_u16<V>(self, visitor: V) -> Result<V::Value>
375 where
376 V: Visitor<'de>,
377 {
378 let text = self.get_text_cow()?;
379 visitor.visit_u16(self.parse_value(&text)?)
380 }
381
382 fn deserialize_u32<V>(self, visitor: V) -> Result<V::Value>
383 where
384 V: Visitor<'de>,
385 {
386 let text = self.get_text_cow()?;
387 visitor.visit_u32(self.parse_value(&text)?)
388 }
389
390 fn deserialize_u64<V>(self, visitor: V) -> Result<V::Value>
391 where
392 V: Visitor<'de>,
393 {
394 let text = self.get_text_cow()?;
395 visitor.visit_u64(self.parse_value(&text)?)
396 }
397
398 fn deserialize_f32<V>(self, visitor: V) -> Result<V::Value>
399 where
400 V: Visitor<'de>,
401 {
402 let text = self.get_text_cow()?;
403 visitor.visit_f32(self.parse_value(&text)?)
404 }
405
406 fn deserialize_f64<V>(self, visitor: V) -> Result<V::Value>
407 where
408 V: Visitor<'de>,
409 {
410 let text = self.get_text_cow()?;
411 visitor.visit_f64(self.parse_value(&text)?)
412 }
413
414 fn deserialize_char<V>(self, visitor: V) -> Result<V::Value>
415 where
416 V: Visitor<'de>,
417 {
418 let text = self.get_text_cow()?;
419 let mut chars = text.chars();
420 match (chars.next(), chars.next()) {
421 (Some(c), None) => visitor.visit_char(c),
422 _ => Err(Error::invalid_value("expected single character")
423 .with_position(self.reader.position())),
424 }
425 }
426
427 fn deserialize_str<V>(self, visitor: V) -> Result<V::Value>
428 where
429 V: Visitor<'de>,
430 {
431 match self.get_text_cow()? {
432 Cow::Borrowed(text) => visitor.visit_borrowed_str(text),
433 Cow::Owned(text) => visitor.visit_string(text),
434 }
435 }
436
437 fn deserialize_string<V>(self, visitor: V) -> Result<V::Value>
438 where
439 V: Visitor<'de>,
440 {
441 let text = self.get_text()?;
442 visitor.visit_string(text)
443 }
444
445 fn deserialize_bytes<V>(self, visitor: V) -> Result<V::Value>
446 where
447 V: Visitor<'de>,
448 {
449 match self.get_text_cow()? {
450 Cow::Borrowed(text) => visitor.visit_borrowed_bytes(text.as_bytes()),
451 Cow::Owned(text) => visitor.visit_byte_buf(text.into_bytes()),
452 }
453 }
454
455 fn deserialize_byte_buf<V>(self, visitor: V) -> Result<V::Value>
456 where
457 V: Visitor<'de>,
458 {
459 self.deserialize_bytes(visitor)
460 }
461
462 fn deserialize_option<V>(self, visitor: V) -> Result<V::Value>
463 where
464 V: Visitor<'de>,
465 {
466 if self.pending_value.is_some() || self.start_consumed {
467 return visitor.visit_some(self);
468 }
469
470 match self.peek_event()? {
471 XmlEvent::EndElement { .. } | XmlEvent::Eof => visitor.visit_none(),
472 _ => visitor.visit_some(self),
473 }
474 }
475
476 fn deserialize_unit<V>(self, visitor: V) -> Result<V::Value>
477 where
478 V: Visitor<'de>,
479 {
480 self.pending_value = None;
481 self.pending_wrapper = false;
482 if self.start_consumed && !self.is_empty_element {
483 if let XmlEvent::EndElement { .. } = self.peek_event()? {
485 self.next_event()?;
486 }
487 }
488 self.start_consumed = false;
489 self.is_empty_element = false;
490 visitor.visit_unit()
491 }
492
493 fn deserialize_unit_struct<V>(self, _name: &'static str, visitor: V) -> Result<V::Value>
494 where
495 V: Visitor<'de>,
496 {
497 self.pending_wrapper = false;
498 if self.start_consumed {
499 if !self.is_empty_element {
500 self.drain_to_matching_end()?;
502 }
503 self.start_consumed = false;
504 self.is_empty_element = false;
505 return visitor.visit_unit();
506 }
507
508 match self.peek_event()? {
509 XmlEvent::EmptyElement { .. } => {
510 self.next_event()?;
511 }
512 XmlEvent::StartElement { .. } => {
513 self.next_event()?;
514 self.drain_to_matching_end()?;
515 }
516 _ => {}
517 }
518 visitor.visit_unit()
519 }
520
521 fn deserialize_newtype_struct<V>(self, _name: &'static str, visitor: V) -> Result<V::Value>
522 where
523 V: Visitor<'de>,
524 {
525 visitor.visit_newtype_struct(self)
526 }
527
528 fn deserialize_seq<V>(self, visitor: V) -> Result<V::Value>
529 where
530 V: Visitor<'de>,
531 {
532 visitor.visit_seq(SeqDeserializer::new(self))
533 }
534
535 fn deserialize_tuple<V>(self, _len: usize, visitor: V) -> Result<V::Value>
536 where
537 V: Visitor<'de>,
538 {
539 self.deserialize_seq(visitor)
540 }
541
542 fn deserialize_tuple_struct<V>(
543 self,
544 _name: &'static str,
545 _len: usize,
546 visitor: V,
547 ) -> Result<V::Value>
548 where
549 V: Visitor<'de>,
550 {
551 self.deserialize_seq(visitor)
552 }
553
554 fn deserialize_map<V>(self, visitor: V) -> Result<V::Value>
555 where
556 V: Visitor<'de>,
557 {
558 self.pending_wrapper = false;
560
561 let text_key = std::mem::replace(&mut self.text_key, "$value");
564
565 let (attrs, is_empty) = if self.start_consumed {
567 self.start_consumed = false;
568 let is_empty = self.is_empty_element;
569 self.is_empty_element = false;
570 (vec![], is_empty)
571 } else {
572 self.skip_ignorable_events()?;
575 match self.next_event()? {
577 XmlEvent::StartElement { attributes, .. } => (attributes, false),
578 XmlEvent::EmptyElement { attributes, .. } => (attributes, true),
579 XmlEvent::Eof => {
580 return Err(Error::unexpected_eof().with_position(self.reader.position()))
581 }
582 _ => (vec![], false),
583 }
584 };
585
586 let result = visitor.visit_map(MapDeserializer {
587 de: self,
588 attrs,
589 attr_idx: 0,
590 finished: is_empty,
591 text_key,
592 })?;
593
594 if !is_empty {
596 self.drain_to_matching_end()?;
597 }
598
599 Ok(result)
600 }
601
602 fn deserialize_struct<V>(
603 self,
604 _name: &'static str,
605 fields: &'static [&'static str],
606 visitor: V,
607 ) -> Result<V::Value>
608 where
609 V: Visitor<'de>,
610 {
611 self.text_key = text_key_for(fields);
613 self.deserialize_map(visitor)
614 }
615
616 fn deserialize_enum<V>(
617 self,
618 _name: &'static str,
619 _variants: &'static [&'static str],
620 visitor: V,
621 ) -> Result<V::Value>
622 where
623 V: Visitor<'de>,
624 {
625 if std::mem::take(&mut self.pending_wrapper) && self.pending_value.is_none() {
629 self.skip_ignorable_events()?;
630 if matches!(self.peek_event()?, XmlEvent::EmptyElement { .. }) {
631 let name = match self.next_event()? {
635 XmlEvent::EmptyElement { name, .. } => name.into_owned(),
636 _ => unreachable!(),
637 };
638 return Err(Error::custom(format!(
639 "cannot deserialize enum from empty element `<{}/>`",
640 name
641 ))
642 .with_position(self.reader.position()));
643 }
644 if matches!(self.peek_event()?, XmlEvent::StartElement { .. }) {
645 self.next_event()?;
646 let value = visitor.visit_enum(EnumDeserializer::new(&mut *self))?;
647
648 self.drain_to_matching_end()?;
650 return Ok(value);
651 }
652 }
653
654 visitor.visit_enum(EnumDeserializer::new(self))
655 }
656
657 fn deserialize_identifier<V>(self, visitor: V) -> Result<V::Value>
658 where
659 V: Visitor<'de>,
660 {
661 self.deserialize_string(visitor)
662 }
663
664 fn deserialize_ignored_any<V>(self, visitor: V) -> Result<V::Value>
665 where
666 V: Visitor<'de>,
667 {
668 self.pending_value = None;
669 self.pending_wrapper = false;
670
671 if self.start_consumed {
672 if !self.is_empty_element {
673 self.skip_element()?;
674 }
675 self.start_consumed = false;
676 self.is_empty_element = false;
677 return visitor.visit_unit();
678 }
679
680 match self.peek_event()? {
681 XmlEvent::StartElement { .. } => {
682 self.next_event()?;
683 self.skip_element()?;
684 }
685 XmlEvent::EmptyElement { .. } => {
686 self.next_event()?;
687 }
688 XmlEvent::Text(_) | XmlEvent::CData(_) => {
689 self.next_event()?;
690 }
691 _ => {}
692 }
693 visitor.visit_unit()
694 }
695}
696
697struct SeqDeserializer<'a, 'de> {
699 de: &'a mut Deserializer<'de>,
700 element_name: Option<String>,
701}
702
703impl<'a, 'de> SeqDeserializer<'a, 'de> {
704 fn new(de: &'a mut Deserializer<'de>) -> Self {
705 Self {
706 de,
707 element_name: None,
708 }
709 }
710}
711
712impl<'de, 'a> SeqAccess<'de> for SeqDeserializer<'a, 'de> {
713 type Error = Error;
714
715 fn next_element_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>>
716 where
717 T: DeserializeSeed<'de>,
718 {
719 loop {
720 match self.de.peek_event()? {
721 XmlEvent::StartElement { name, .. } | XmlEvent::EmptyElement { name, .. } => {
722 if let Some(ref expected) = self.element_name {
723 if name.as_ref() != expected.as_str() {
724 return Ok(None);
725 }
726 } else {
727 self.element_name = Some(name.clone().into_owned());
728 }
729
730 self.de.pending_wrapper = true;
733 return seed.deserialize(&mut *self.de).map(Some);
734 }
735 XmlEvent::EndElement { .. } | XmlEvent::Eof => return Ok(None),
736 XmlEvent::Text(_) | XmlEvent::CData(_) => {
737 return seed.deserialize(&mut *self.de).map(Some);
738 }
739 _ => {
740 self.de.next_event()?;
741 }
742 }
743 }
744 }
745}
746
747struct MapDeserializer<'a, 'de> {
749 de: &'a mut Deserializer<'de>,
750 attrs: Vec<Attribute<'de>>,
751 attr_idx: usize,
752 finished: bool,
753 text_key: &'static str,
755}
756
757impl<'de, 'a> MapAccess<'de> for MapDeserializer<'a, 'de> {
758 type Error = Error;
759
760 fn next_key_seed<K>(&mut self, seed: K) -> Result<Option<K::Value>>
761 where
762 K: DeserializeSeed<'de>,
763 {
764 if self.attr_idx < self.attrs.len() {
766 let name = &self.attrs[self.attr_idx].name;
767 let mut key = String::with_capacity(name.len() + 1);
769 key.push('@');
770 key.push_str(name);
771 self.de.pending_value = Some(Cow::Owned(key));
772 return seed.deserialize(&mut *self.de).map(Some);
773 }
774
775 if self.finished {
776 return Ok(None);
777 }
778
779 loop {
781 match self.de.peek_event()? {
782 XmlEvent::StartElement { name, .. } | XmlEvent::EmptyElement { name, .. } => {
783 let name = name.clone();
784 self.de.pending_value = Some(name);
786 return seed.deserialize(&mut *self.de).map(Some);
787 }
788 XmlEvent::EndElement { .. } | XmlEvent::Eof => {
789 self.finished = true;
790 return Ok(None);
791 }
792 XmlEvent::Text(_) | XmlEvent::CData(_) => {
793 self.de.pending_value = Some(Cow::Borrowed(self.text_key));
794 return seed.deserialize(&mut *self.de).map(Some);
795 }
796 _ => {
797 self.de.next_event()?;
798 }
799 }
800 }
801 }
802
803 fn next_value_seed<V>(&mut self, seed: V) -> Result<V::Value>
804 where
805 V: DeserializeSeed<'de>,
806 {
807 if self.attr_idx < self.attrs.len() {
810 let value = &self.attrs[self.attr_idx].value;
811 self.attr_idx += 1;
812 self.de.pending_value = Some(value.clone());
813 return seed.deserialize(&mut *self.de);
814 }
815
816 self.de.pending_wrapper = true;
819 seed.deserialize(&mut *self.de)
820 }
821}
822
823struct EnumDeserializer<'a, 'de> {
825 de: &'a mut Deserializer<'de>,
826}
827
828impl<'a, 'de> EnumDeserializer<'a, 'de> {
829 fn new(de: &'a mut Deserializer<'de>) -> Self {
830 Self { de }
831 }
832}
833
834impl<'de, 'a> de::EnumAccess<'de> for EnumDeserializer<'a, 'de> {
835 type Error = Error;
836 type Variant = Self;
837
838 fn variant_seed<V>(self, seed: V) -> Result<(V::Value, Self::Variant)>
839 where
840 V: DeserializeSeed<'de>,
841 {
842 if self.de.pending_value.is_some() {
844 let variant = seed.deserialize(&mut *self.de)?;
845 return Ok((variant, self));
846 }
847
848 match self.de.peek_event()? {
850 XmlEvent::StartElement { name, .. } | XmlEvent::EmptyElement { name, .. } => {
851 let name = name.clone();
852 self.de.pending_value = Some(name);
853 }
854 XmlEvent::Text(text) => {
855 let text = text.clone();
856 self.de.pending_value = Some(text);
857 }
858 _ => {}
859 }
860
861 let variant = seed.deserialize(&mut *self.de)?;
862 Ok((variant, self))
863 }
864}
865
866impl<'de, 'a> de::VariantAccess<'de> for EnumDeserializer<'a, 'de> {
867 type Error = Error;
868
869 fn unit_variant(self) -> Result<()> {
870 if self.de.start_consumed {
871 if !self.de.is_empty_element {
872 self.de.skip_element()?;
873 }
874 self.de.start_consumed = false;
875 self.de.is_empty_element = false;
876 return Ok(());
877 }
878
879 match self.de.peek_event()? {
880 XmlEvent::EmptyElement { .. } => {
881 self.de.next_event()?;
882 }
883 XmlEvent::StartElement { .. } => {
884 self.de.next_event()?;
885 self.de.skip_element()?;
886 }
887 _ => {}
888 }
889 Ok(())
890 }
891
892 fn newtype_variant_seed<T>(self, seed: T) -> Result<T::Value>
893 where
894 T: DeserializeSeed<'de>,
895 {
896 self.de.pending_wrapper = true;
899 seed.deserialize(&mut *self.de)
900 }
901
902 fn tuple_variant<V>(self, _len: usize, visitor: V) -> Result<V::Value>
903 where
904 V: Visitor<'de>,
905 {
906 if matches!(self.de.peek_event()?, XmlEvent::StartElement { .. }) {
909 self.de.next_event()?;
910 let value = de::Deserializer::deserialize_seq(&mut *self.de, visitor)?;
911 if let XmlEvent::EndElement { .. } = self.de.peek_event()? {
913 self.de.next_event()?;
914 }
915 return Ok(value);
916 }
917 de::Deserializer::deserialize_seq(&mut *self.de, visitor)
918 }
919
920 fn struct_variant<V>(self, fields: &'static [&'static str], visitor: V) -> Result<V::Value>
921 where
922 V: Visitor<'de>,
923 {
924 self.de.text_key = text_key_for(fields);
927 de::Deserializer::deserialize_map(&mut *self.de, visitor)
928 }
929}
930
931#[cfg(test)]
932mod tests {
933 use super::*;
934 use serde::{Deserialize, Serialize};
935
936 #[test]
937 fn test_deserialize_simple_struct() {
938 #[derive(Debug, Deserialize, PartialEq)]
939 struct Person {
940 name: String,
941 age: u32,
942 }
943
944 let xml = "<Person><name>Alice</name><age>30</age></Person>";
945 let person: Person = from_str(xml).unwrap();
946 assert_eq!(person.name, "Alice");
947 assert_eq!(person.age, 30);
948 }
949
950 #[test]
951 fn test_deserialize_with_attributes() {
952 #[derive(Debug, Deserialize, PartialEq)]
953 struct Item {
954 #[serde(rename = "@id")]
955 id: String,
956 name: String,
957 }
958
959 let xml = r#"<Item id="123"><name>Widget</name></Item>"#;
960 let item: Item = from_str(xml).unwrap();
961 assert_eq!(item.id, "123");
962 assert_eq!(item.name, "Widget");
963 }
964
965 #[test]
966 fn test_deserialize_nested_struct() {
967 #[derive(Debug, Deserialize, PartialEq)]
968 struct Address {
969 city: String,
970 country: String,
971 }
972
973 #[derive(Debug, Deserialize, PartialEq)]
974 struct Person {
975 name: String,
976 address: Address,
977 }
978
979 let xml = r#"
980 <Person>
981 <name>Bob</name>
982 <address>
983 <city>New York</city>
984 <country>USA</country>
985 </address>
986 </Person>
987 "#;
988 let person: Person = from_str(xml).unwrap();
989 assert_eq!(person.name, "Bob");
990 assert_eq!(person.address.city, "New York");
991 }
992
993 #[test]
994 fn test_deserialize_optional() {
995 #[derive(Debug, Deserialize, PartialEq)]
996 struct Config {
997 name: String,
998 #[serde(default)]
999 value: Option<String>,
1000 }
1001
1002 let xml1 = "<Config><name>test</name><value>val</value></Config>";
1003 let config1: Config = from_str(xml1).unwrap();
1004 assert_eq!(config1.value, Some("val".to_string()));
1005
1006 let xml2 = "<Config><name>test</name></Config>";
1007 let config2: Config = from_str(xml2).unwrap();
1008 assert_eq!(config2.value, None);
1009 }
1010
1011 #[test]
1012 fn test_deserialize_bool() {
1013 #[derive(Debug, Deserialize, PartialEq)]
1014 struct Flags {
1015 enabled: bool,
1016 active: bool,
1017 }
1018
1019 let xml = "<Flags><enabled>true</enabled><active>false</active></Flags>";
1020 let flags: Flags = from_str(xml).unwrap();
1021 assert!(flags.enabled);
1022 assert!(!flags.active);
1023 }
1024
1025 #[test]
1026 fn test_deserialize_numbers() {
1027 #[derive(Debug, Deserialize, PartialEq)]
1028 struct Numbers {
1029 i: i32,
1030 u: u64,
1031 f: f64,
1032 }
1033
1034 let xml = "<Numbers><i>-42</i><u>100</u><f>1.234</f></Numbers>";
1035 let nums: Numbers = from_str(xml).unwrap();
1036 assert_eq!(nums.i, -42);
1037 assert_eq!(nums.u, 100);
1038 assert!((nums.f - 1.234).abs() < 0.001);
1039 }
1040
1041 #[test]
1042 fn test_deserialize_vector() {
1043 #[derive(Debug, Deserialize, PartialEq)]
1044 struct Items {
1045 item: Vec<String>,
1046 }
1047
1048 let xml = r#"<Items><item>one</item><item>two</item><item>three</item></Items>"#;
1049 let items: Items = from_str(xml).unwrap();
1050 assert_eq!(items.item, vec!["one", "two", "three"]);
1051 }
1052
1053 #[test]
1054 fn test_deserialize_escaped_content() {
1055 #[derive(Debug, Deserialize, PartialEq)]
1056 struct Data {
1057 content: String,
1058 }
1059
1060 let xml = "<Data><content><hello> & "world"</content></Data>";
1061 let data: Data = from_str(xml).unwrap();
1062 assert_eq!(data.content, "<hello> & \"world\"");
1063 }
1064
1065 #[test]
1066 fn test_deserialize_empty_element() {
1067 #[derive(Debug, Deserialize, PartialEq)]
1068 struct Empty {
1069 #[serde(default)]
1070 value: String,
1071 }
1072
1073 let xml = "<Empty><value></value></Empty>";
1074 let empty: Empty = from_str(xml).unwrap();
1075 assert_eq!(empty.value, "");
1076 }
1077
1078 #[test]
1079 fn test_deserialize_char() {
1080 #[derive(Debug, Deserialize, PartialEq)]
1081 struct Data {
1082 c: char,
1083 }
1084
1085 let xml = "<Data><c>A</c></Data>";
1086 let data: Data = from_str(xml).unwrap();
1087 assert_eq!(data.c, 'A');
1088 }
1089
1090 #[test]
1091 fn test_deserialize_unit_struct() {
1092 #[derive(Debug, Deserialize, PartialEq)]
1093 struct Unit;
1094
1095 let xml = "<Unit/>";
1096 let _unit: Unit = from_str(xml).unwrap();
1097 }
1098
1099 #[test]
1100 fn test_from_bytes() {
1101 #[derive(Debug, Deserialize, PartialEq)]
1102 struct Data {
1103 value: String,
1104 }
1105
1106 let bytes = b"<Data><value>test</value></Data>";
1107 let data: Data = from_bytes(bytes).unwrap();
1108 assert_eq!(data.value, "test");
1109 }
1110
1111 #[test]
1112 fn test_deserialize_vector_of_structs() {
1113 #[derive(Debug, Deserialize, PartialEq)]
1114 struct Item {
1115 name: String,
1116 count: u32,
1117 }
1118
1119 #[derive(Debug, Deserialize, PartialEq)]
1120 struct Items {
1121 item: Vec<Item>,
1122 }
1123
1124 let xml = r#"<Items><item><name>A</name><count>1</count></item><item><name>B</name><count>2</count></item></Items>"#;
1125 let items: Items = from_str(xml).unwrap();
1126 assert_eq!(items.item.len(), 2);
1127 assert_eq!(items.item[0].name, "A");
1128 assert_eq!(items.item[1].name, "B");
1129 }
1130
1131 #[test]
1132 fn test_deserialize_multiple_attributes() {
1133 #[derive(Debug, Deserialize, PartialEq)]
1134 struct Element {
1135 #[serde(rename = "@id")]
1136 id: String,
1137 #[serde(rename = "@class")]
1138 class: String,
1139 name: String,
1140 }
1141
1142 let xml = r#"<Element id="main" class="container"><name>Test</name></Element>"#;
1143 let elem: Element = from_str(xml).unwrap();
1144 assert_eq!(elem.id, "main");
1145 assert_eq!(elem.class, "container");
1146 assert_eq!(elem.name, "Test");
1147 }
1148
1149 #[test]
1150 fn test_deserialize_attributes_with_special_chars() {
1151 #[derive(Debug, Deserialize, PartialEq)]
1152 struct Element {
1153 #[serde(rename = "@title")]
1154 title: String,
1155 }
1156
1157 let xml = r#"<Element title="Hello & "World""/>"#;
1158 let elem: Element = from_str(xml).unwrap();
1159 assert_eq!(elem.title, "Hello & \"World\"");
1160 }
1161
1162 #[test]
1163 fn test_deserialize_numeric_attributes() {
1164 #[derive(Debug, Deserialize, PartialEq)]
1165 struct Item {
1166 #[serde(rename = "@id")]
1167 id: u32,
1168 #[serde(rename = "@count")]
1169 count: i32,
1170 #[serde(rename = "@price")]
1171 price: f64,
1172 #[serde(rename = "@active")]
1173 active: bool,
1174 }
1175
1176 let xml = r#"<Item id="42" count="-10" price="19.99" active="true"/>"#;
1177 let item: Item = from_str(xml).unwrap();
1178 assert_eq!(item.id, 42);
1179 assert_eq!(item.count, -10);
1180 assert!((item.price - 19.99).abs() < 0.001);
1181 assert!(item.active);
1182 }
1183
1184 #[test]
1185 fn test_deserialize_empty_element_with_attributes() {
1186 #[derive(Debug, Deserialize, PartialEq)]
1187 struct Empty {
1188 #[serde(rename = "@id")]
1189 id: String,
1190 #[serde(default)]
1191 value: String,
1192 }
1193
1194 let xml = r#"<Empty id="test"/>"#;
1195 let elem: Empty = from_str(xml).unwrap();
1196 assert_eq!(elem.id, "test");
1197 assert_eq!(elem.value, "");
1198 }
1199
1200 #[test]
1201 fn test_deserialize_nested_with_attributes() {
1202 #[derive(Debug, Deserialize, PartialEq)]
1203 struct Child {
1204 #[serde(rename = "@name")]
1205 name: String,
1206 }
1207
1208 #[derive(Debug, Deserialize, PartialEq)]
1209 struct Parent {
1210 #[serde(rename = "@id")]
1211 id: String,
1212 child: Child,
1213 }
1214
1215 let xml = r#"<Parent id="p1"><child name="c1"/></Parent>"#;
1216 let parent: Parent = from_str(xml).unwrap();
1217 assert_eq!(parent.id, "p1");
1218 assert_eq!(parent.child.name, "c1");
1219 }
1220
1221 #[test]
1222 fn test_deserialize_vector_with_attributes() {
1223 #[derive(Debug, Deserialize, PartialEq)]
1224 struct Item {
1225 #[serde(rename = "@id")]
1226 id: u32,
1227 name: String,
1228 }
1229
1230 #[derive(Debug, Deserialize, PartialEq)]
1231 struct List {
1232 #[serde(rename = "@version")]
1233 version: String,
1234 item: Vec<Item>,
1235 }
1236
1237 let xml = r#"<List version="1.0"><item id="1"><name>A</name></item><item id="2"><name>B</name></item></List>"#;
1238 let list: List = from_str(xml).unwrap();
1239 assert_eq!(list.version, "1.0");
1240 assert_eq!(list.item.len(), 2);
1241 assert_eq!(list.item[0].id, 1);
1242 assert_eq!(list.item[1].id, 2);
1243 }
1244
1245 #[test]
1246 fn test_deserialize_value_text_with_attribute() {
1247 #[derive(Debug, Deserialize, PartialEq)]
1248 struct Link {
1249 #[serde(rename = "@href")]
1250 href: String,
1251 #[serde(rename = "$value")]
1252 value: String,
1253 }
1254
1255 let xml = r#"<Link href="https://example.com">Example</Link>"#;
1256 let link: Link = from_str(xml).unwrap();
1257 assert_eq!(link.href, "https://example.com");
1258 assert_eq!(link.value, "Example");
1259 }
1260
1261 #[test]
1262 fn test_round_trip_text_rename_with_attribute() {
1263 #[derive(Debug, Serialize, Deserialize, PartialEq)]
1264 struct Link {
1265 #[serde(rename = "@href")]
1266 href: String,
1267 #[serde(rename = "$text")]
1268 text: String,
1269 }
1270
1271 let link = Link {
1272 href: "https://example.com".to_string(),
1273 text: "Example".to_string(),
1274 };
1275
1276 let xml = crate::to_string(&link).unwrap();
1277 let parsed: Link = from_str(&xml).unwrap();
1278 assert_eq!(parsed, link);
1279 }
1280
1281 #[test]
1282 fn test_deserialize_text_rename() {
1283 #[derive(Debug, Deserialize, PartialEq)]
1284 struct Link {
1285 #[serde(rename = "@href")]
1286 href: String,
1287 #[serde(rename = "$text")]
1288 text: String,
1289 }
1290
1291 let xml = r#"<Link href="https://example.com">Example</Link>"#;
1292 let link: Link = from_str(xml).unwrap();
1293 assert_eq!(link.href, "https://example.com");
1294 assert_eq!(link.text, "Example");
1295 }
1296
1297 #[test]
1298 fn test_invalid_number_error_has_position() {
1299 #[derive(Debug, Deserialize)]
1300 struct Person {
1301 age: u32,
1302 }
1303
1304 let xml = "<Person><age>abc</age></Person>";
1305 let err = from_str::<Person>(xml).unwrap_err();
1306 let pos = err.position().expect("error should carry a position");
1309 assert_eq!(pos.line, 1);
1310 assert_eq!(pos.column, 23);
1311 assert_eq!(pos.offset, 22);
1312
1313 let person: Person = from_str("<Person><age>30</age></Person>").unwrap();
1315 assert_eq!(person.age, 30);
1316 }
1317
1318 #[test]
1319 fn test_deserialize_borrowed_str() {
1320 #[derive(Debug, Deserialize, PartialEq)]
1321 struct Borrowed<'a> {
1322 #[serde(borrow)]
1323 name: &'a str,
1324 }
1325
1326 let xml = "<Borrowed><name>hi</name></Borrowed>";
1327 let borrowed: Borrowed<'_> = from_str(xml).unwrap();
1328 assert_eq!(borrowed.name, "hi");
1329 }
1330
1331 #[test]
1332 fn test_deserialize_skips_comments_and_pis() {
1333 #[derive(Debug, Deserialize, PartialEq)]
1334 struct Person {
1335 name: String,
1336 age: u32,
1337 }
1338
1339 let xml = "<Person><!-- a comment --><name>Alice</name><?pi data?><age>30</age><!-- trailing --></Person>";
1340 let person: Person = from_str(xml).unwrap();
1341 assert_eq!(person.name, "Alice");
1342 assert_eq!(person.age, 30);
1343 }
1344
1345 #[test]
1346 fn test_invalid_bool_error_has_position() {
1347 #[derive(Debug, Deserialize)]
1348 struct Flags {
1349 b: bool,
1350 }
1351
1352 let xml = "<a><b>maybe</b></a>";
1353 let err = from_str::<Flags>(xml).unwrap_err();
1354 let pos = err.position().expect("error should carry a position");
1357 assert_eq!(pos.line, 1);
1358 assert_eq!(pos.column, 16);
1359 assert_eq!(pos.offset, 15);
1360
1361 let flags: Flags = from_str("<a><b>yes</b></a>").unwrap();
1363 assert!(flags.b);
1364 }
1365
1366 #[test]
1367 fn test_invalid_char_error_has_position() {
1368 #[derive(Debug, Deserialize)]
1369 struct Data {
1370 c: char,
1371 }
1372
1373 let xml = "<Data><c>abc</c></Data>";
1374 let err = from_str::<Data>(xml).unwrap_err();
1375 let pos = err.position().expect("error should carry a position");
1378 assert_eq!(pos.line, 1);
1379 assert_eq!(pos.column, 17);
1380 assert_eq!(pos.offset, 16);
1381
1382 let data: Data = from_str("<Data><c>x</c></Data>").unwrap();
1384 assert_eq!(data.c, 'x');
1385 }
1386
1387 #[test]
1388 fn test_deserialize_borrowed_attribute() {
1389 #[derive(Debug, Deserialize, PartialEq)]
1390 struct Tag<'a> {
1391 #[serde(rename = "@href", borrow)]
1392 href: &'a str,
1393 }
1394
1395 let xml = r#"<Tag href="x"/>"#;
1396 let tag: Tag<'_> = from_str(xml).unwrap();
1397 assert_eq!(tag.href, "x");
1398 }
1399
1400 #[test]
1401 fn test_deserialize_escaped_attribute_falls_back_to_owned() {
1402 #[derive(Debug, Deserialize, PartialEq)]
1403 struct Tag<'a> {
1404 #[serde(rename = "@href", borrow)]
1405 href: Cow<'a, str>,
1406 }
1407
1408 let xml = r#"<Tag href="a & b"/>"#;
1409 let tag: Tag<'_> = from_str(xml).unwrap();
1410 assert_eq!(tag.href, "a & b");
1411 assert!(matches!(tag.href, Cow::Owned(_)));
1412 }
1413
1414 #[test]
1415 fn test_deserialize_comment_before_root() {
1416 #[derive(Debug, Deserialize, PartialEq)]
1417 struct Person {
1418 name: String,
1419 age: u32,
1420 }
1421
1422 let xml = "<!-- leading --><Person><name>Alice</name><age>30</age></Person>";
1423 let person: Person = from_str(xml).unwrap();
1424 assert_eq!(person.name, "Alice");
1425 assert_eq!(person.age, 30);
1426 }
1427
1428 #[test]
1429 fn test_deserialize_pi_before_root() {
1430 #[derive(Debug, Deserialize, PartialEq)]
1431 struct Person {
1432 name: String,
1433 age: u32,
1434 }
1435
1436 let xml = "<?pi data?><Person><name>Alice</name><age>30</age></Person>";
1437 let person: Person = from_str(xml).unwrap();
1438 assert_eq!(person.name, "Alice");
1439 assert_eq!(person.age, 30);
1440 }
1441
1442 #[test]
1443 fn test_deserialize_xml_decl_before_root() {
1444 #[derive(Debug, Deserialize, PartialEq)]
1445 struct Person {
1446 name: String,
1447 age: u32,
1448 }
1449
1450 let xml = r#"<?xml version="1.0"?><Person><name>Alice</name><age>30</age></Person>"#;
1451 let person: Person = from_str(xml).unwrap();
1452 assert_eq!(person.name, "Alice");
1453 assert_eq!(person.age, 30);
1454 }
1455
1456 #[test]
1457 fn test_round_trip_enum_field_unit_variant() {
1458 #[derive(Debug, Serialize, Deserialize, PartialEq)]
1459 enum Status {
1460 Active,
1461 Inactive,
1462 }
1463
1464 #[derive(Debug, Serialize, Deserialize, PartialEq)]
1465 struct Item {
1466 status: Status,
1467 name: String,
1468 }
1469
1470 let item = Item {
1471 status: Status::Active,
1472 name: "widget".to_string(),
1473 };
1474
1475 let xml = crate::to_string(&item).unwrap();
1476 let parsed: Item = from_str(&xml).unwrap();
1477 assert_eq!(parsed, item);
1478
1479 let item = Item {
1480 status: Status::Inactive,
1481 name: "gadget".to_string(),
1482 };
1483
1484 let xml = crate::to_string(&item).unwrap();
1485 let parsed: Item = from_str(&xml).unwrap();
1486 assert_eq!(parsed, item);
1487 }
1488
1489 #[test]
1490 fn test_round_trip_enum_field_newtype_variant() {
1491 #[derive(Debug, Serialize, Deserialize, PartialEq)]
1492 enum Status {
1493 Count(u32),
1494 }
1495
1496 #[derive(Debug, Serialize, Deserialize, PartialEq)]
1497 struct Item {
1498 status: Status,
1499 name: String,
1500 }
1501
1502 let item = Item {
1503 status: Status::Count(42),
1504 name: "widget".to_string(),
1505 };
1506
1507 let xml = crate::to_string(&item).unwrap();
1508 let parsed: Item = from_str(&xml).unwrap();
1509 assert_eq!(parsed, item);
1510 }
1511
1512 #[test]
1513 fn test_round_trip_enum_field_tuple_variant() {
1514 #[derive(Debug, Serialize, Deserialize, PartialEq)]
1515 enum Status {
1516 Pair(u32, String),
1517 }
1518
1519 #[derive(Debug, Serialize, Deserialize, PartialEq)]
1520 struct Item {
1521 status: Status,
1522 name: String,
1523 }
1524
1525 let item = Item {
1526 status: Status::Pair(1, "one".to_string()),
1527 name: "widget".to_string(),
1528 };
1529
1530 let xml = crate::to_string(&item).unwrap();
1531 let parsed: Item = from_str(&xml).unwrap();
1532 assert_eq!(parsed, item);
1533 }
1534
1535 #[test]
1536 fn test_round_trip_enum_field_struct_variant() {
1537 #[derive(Debug, Serialize, Deserialize, PartialEq)]
1538 enum Status {
1539 Point { x: i32, y: i32 },
1540 }
1541
1542 #[derive(Debug, Serialize, Deserialize, PartialEq)]
1543 struct Item {
1544 status: Status,
1545 name: String,
1546 }
1547
1548 let item = Item {
1549 status: Status::Point { x: 1, y: 2 },
1550 name: "widget".to_string(),
1551 };
1552
1553 let xml = crate::to_string(&item).unwrap();
1554 let parsed: Item = from_str(&xml).unwrap();
1555 assert_eq!(parsed, item);
1556 }
1557
1558 #[test]
1559 fn test_round_trip_enum_field_struct_variant_text() {
1560 #[derive(Debug, Serialize, Deserialize, PartialEq)]
1561 enum Content {
1562 Message {
1563 #[serde(rename = "@lang")]
1564 lang: String,
1565 #[serde(rename = "$text")]
1566 text: String,
1567 },
1568 }
1569
1570 #[derive(Debug, Serialize, Deserialize, PartialEq)]
1571 struct Doc {
1572 content: Content,
1573 footer: String,
1574 }
1575
1576 let doc = Doc {
1577 content: Content::Message {
1578 lang: "en".to_string(),
1579 text: "hello".to_string(),
1580 },
1581 footer: "bye".to_string(),
1582 };
1583
1584 let xml = crate::to_string(&doc).unwrap();
1585 let parsed: Doc = from_str(&xml).unwrap();
1586 assert_eq!(parsed, doc);
1587 }
1588
1589 #[test]
1590 fn test_deserialize_top_level_enum_variants() {
1591 #[derive(Debug, Serialize, Deserialize, PartialEq)]
1592 enum Value {
1593 Unit,
1594 Count(u32),
1595 Pair(u32, String),
1596 Point { x: i32, y: i32 },
1597 }
1598
1599 let unit: Value = from_str("<Unit/>").unwrap();
1600 assert_eq!(unit, Value::Unit);
1601
1602 let count: Value = from_str("<Count>42</Count>").unwrap();
1603 assert_eq!(count, Value::Count(42));
1604
1605 let pair: Value = from_str("<Pair><item>1</item><item>one</item></Pair>").unwrap();
1606 assert_eq!(pair, Value::Pair(1, "one".to_string()));
1607
1608 let point: Value = from_str("<Point><x>1</x><y>2</y></Point>").unwrap();
1609 assert_eq!(point, Value::Point { x: 1, y: 2 });
1610 }
1611
1612 #[test]
1613 fn test_deserialize_cdata_content() {
1614 #[derive(Debug, Deserialize, PartialEq)]
1615 struct Data {
1616 content: String,
1617 }
1618
1619 let xml = "<Data><content><![CDATA[<raw> & stuff]]></content></Data>";
1620 let data: Data = from_str(xml).unwrap();
1621 assert_eq!(data.content, "<raw> & stuff");
1622 }
1623
1624 #[test]
1625 fn test_from_bytes_invalid_utf8_has_position() {
1626 let bytes = b"<a>\n\xff</a>";
1629 let err = from_bytes::<String>(bytes).unwrap_err();
1630 let pos = err.position().expect("error should carry a position");
1631 assert_eq!(pos.line, 2);
1632 assert_eq!(pos.column, 1);
1633 assert_eq!(pos.offset, 4);
1634 }
1635
1636 #[test]
1637 fn test_deserialize_mixed_text_and_cdata() {
1638 #[derive(Debug, Deserialize, PartialEq)]
1639 struct Data {
1640 content: String,
1641 }
1642
1643 let xml = "<Data><content>a<![CDATA[<b>]]>c</content></Data>";
1644 let data: Data = from_str(xml).unwrap();
1645 assert_eq!(data.content, "a<b>c");
1646 }
1647
1648 #[test]
1649 fn test_deserialize_bytes_borrowed() {
1650 #[derive(Debug, PartialEq)]
1651 struct Bytes<'a>(Cow<'a, [u8]>);
1652
1653 impl<'de: 'a, 'a> Deserialize<'de> for Bytes<'a> {
1654 fn deserialize<D>(deserializer: D) -> std::result::Result<Self, D::Error>
1655 where
1656 D: de::Deserializer<'de>,
1657 {
1658 struct BytesVisitor;
1659
1660 impl<'de> Visitor<'de> for BytesVisitor {
1661 type Value = Bytes<'de>;
1662
1663 fn expecting(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1664 f.write_str("bytes")
1665 }
1666
1667 fn visit_borrowed_bytes<E>(
1668 self,
1669 v: &'de [u8],
1670 ) -> std::result::Result<Self::Value, E> {
1671 Ok(Bytes(Cow::Borrowed(v)))
1672 }
1673
1674 fn visit_byte_buf<E>(self, v: Vec<u8>) -> std::result::Result<Self::Value, E> {
1675 Ok(Bytes(Cow::Owned(v)))
1676 }
1677 }
1678
1679 deserializer.deserialize_bytes(BytesVisitor)
1680 }
1681 }
1682
1683 #[derive(Debug, Deserialize, PartialEq)]
1684 struct Doc<'a> {
1685 #[serde(borrow)]
1686 b: Bytes<'a>,
1687 }
1688
1689 let xml = "<D><b>hi</b></D>";
1691 let doc: Doc<'_> = from_str(xml).unwrap();
1692 assert_eq!(doc.b.0.as_ref(), b"hi");
1693 assert!(matches!(doc.b.0, Cow::Borrowed(_)));
1694
1695 let xml = "<D><b>a & b</b></D>";
1697 let doc: Doc<'_> = from_str(xml).unwrap();
1698 assert_eq!(doc.b.0.as_ref(), b"a & b");
1699 assert!(matches!(doc.b.0, Cow::Owned(_)));
1700 }
1701
1702 #[test]
1703 fn test_deserialize_ignores_unknown_nested_element() {
1704 #[derive(Debug, Deserialize, PartialEq)]
1705 struct Person {
1706 name: String,
1707 }
1708
1709 let xml = "<Person><name>Alice</name><extra><deep>x</deep></extra></Person>";
1710 let person: Person = from_str(xml).unwrap();
1711 assert_eq!(person.name, "Alice");
1712
1713 #[derive(Debug, Deserialize, PartialEq)]
1716 struct People {
1717 person: Vec<Person>,
1718 }
1719
1720 let xml = "<People>\
1721 <person><name>Alice</name><extra><deep>x</deep></extra></person>\
1722 <person><name>Bob</name></person>\
1723 </People>";
1724 let people: People = from_str(xml).unwrap();
1725 assert_eq!(
1726 people.person,
1727 vec![
1728 Person {
1729 name: "Alice".to_string()
1730 },
1731 Person {
1732 name: "Bob".to_string()
1733 },
1734 ]
1735 );
1736 }
1737
1738 #[test]
1739 fn test_deserialize_empty_input_errors() {
1740 #[derive(Debug, Deserialize, PartialEq)]
1741 struct Person {
1742 name: String,
1743 age: u32,
1744 }
1745
1746 let err = from_str::<Person>("").unwrap_err();
1747 assert!(matches!(
1748 err.kind(),
1749 crate::error::ErrorKind::UnexpectedEof
1750 ));
1751 }
1752
1753 #[test]
1754 fn test_deserialize_unit_struct_truncated_errors() {
1755 #[derive(Debug, Deserialize, PartialEq)]
1756 struct Unit;
1757
1758 assert!(from_str::<Unit>("<Unit>").is_err());
1760 }
1761
1762 #[test]
1763 fn test_deserialize_enum_field_empty_element_errors() {
1764 #[derive(Debug, Deserialize, PartialEq)]
1765 enum Status {
1766 Active,
1767 }
1768
1769 #[derive(Debug, Deserialize, PartialEq)]
1770 struct S {
1771 status: Status,
1772 }
1773
1774 let err = from_str::<S>("<S><status/></S>").unwrap_err();
1775 assert!(err.to_string().contains("empty element `<status/>`"));
1776 }
1777}