1use crate::de::{deserialize_bool, str2bool, Text};
7use crate::encoding::Decoder;
8use crate::errors::serialize::DeError;
9use crate::escape::unescape;
10use crate::utils::CowRef;
11use memchr::memchr;
12use serde::de::{DeserializeSeed, Deserializer, EnumAccess, SeqAccess, VariantAccess, Visitor};
13use serde::{self, serde_if_integer128};
14use std::borrow::Cow;
15use std::ops::Range;
16
17macro_rules! deserialize_num {
18 ($method:ident, $visit:ident) => {
19 fn $method<V>(self, visitor: V) -> Result<V::Value, Self::Error>
20 where
21 V: Visitor<'de>,
22 {
23 visitor.$visit(self.content.as_str().parse()?)
24 }
25 };
26 ($method:ident => $visit:ident) => {
27 fn $method<V>(self, visitor: V) -> Result<V::Value, Self::Error>
28 where
29 V: Visitor<'de>,
30 {
31 let string = self.decode()?;
32 visitor.$visit(string.as_str().parse()?)
33 }
34 };
35}
36
37macro_rules! unsupported {
38 (
39 $deserialize:ident
40 $(
41 ($($type:ty),*)
42 )?
43 => $message:literal
44 ) => {
45 #[inline]
46 fn $deserialize<V: Visitor<'de>>(
47 self,
48 $($(_: $type,)*)?
49 _visitor: V
50 ) -> Result<V::Value, Self::Error> {
51 Err(DeError::Unsupported($message.into()))
52 }
53 };
54}
55
56enum Content<'de, 'a> {
65 Input(&'de str),
67 Slice(&'a str),
69 Owned(String, usize),
74}
75impl<'de, 'a> Content<'de, 'a> {
76 fn as_str(&self) -> &str {
78 match self {
79 Content::Input(s) => s,
80 Content::Slice(s) => s,
81 Content::Owned(s, offset) => s.split_at(*offset).1,
82 }
83 }
84
85 #[inline]
94 fn deserialize_all<V>(self, visitor: V) -> Result<V::Value, DeError>
95 where
96 V: Visitor<'de>,
97 {
98 match self {
99 Content::Input(s) => visitor.visit_borrowed_str(s),
100 Content::Slice(s) => visitor.visit_str(s),
101 Content::Owned(s, _) => visitor.visit_string(s),
102 }
103 }
104
105 #[inline]
114 fn deserialize_item<V>(self, visitor: V) -> Result<V::Value, DeError>
115 where
116 V: Visitor<'de>,
117 {
118 match self {
119 Content::Input(s) => visitor.visit_borrowed_str(s),
120 Content::Slice(s) => visitor.visit_str(s),
121 Content::Owned(s, 0) => visitor.visit_string(s),
122 Content::Owned(s, offset) => visitor.visit_str(s.split_at(offset).1),
123 }
124 }
125}
126
127struct AtomicDeserializer<'de, 'a> {
149 content: Content<'de, 'a>,
151 escaped: bool,
153}
154
155impl<'de, 'a> Deserializer<'de> for AtomicDeserializer<'de, 'a> {
156 type Error = DeError;
157
158 fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Self::Error>
160 where
161 V: Visitor<'de>,
162 {
163 self.deserialize_str(visitor)
164 }
165
166 fn deserialize_bool<V>(self, visitor: V) -> Result<V::Value, Self::Error>
175 where
176 V: Visitor<'de>,
177 {
178 str2bool(self.content.as_str(), visitor)
179 }
180
181 deserialize_num!(deserialize_i8, visit_i8);
182 deserialize_num!(deserialize_i16, visit_i16);
183 deserialize_num!(deserialize_i32, visit_i32);
184 deserialize_num!(deserialize_i64, visit_i64);
185
186 deserialize_num!(deserialize_u8, visit_u8);
187 deserialize_num!(deserialize_u16, visit_u16);
188 deserialize_num!(deserialize_u32, visit_u32);
189 deserialize_num!(deserialize_u64, visit_u64);
190
191 serde_if_integer128! {
192 deserialize_num!(deserialize_i128, visit_i128);
193 deserialize_num!(deserialize_u128, visit_u128);
194 }
195
196 deserialize_num!(deserialize_f32, visit_f32);
197 deserialize_num!(deserialize_f64, visit_f64);
198
199 fn deserialize_char<V>(self, visitor: V) -> Result<V::Value, Self::Error>
201 where
202 V: Visitor<'de>,
203 {
204 self.deserialize_str(visitor)
205 }
206
207 fn deserialize_str<V>(self, visitor: V) -> Result<V::Value, Self::Error>
218 where
219 V: Visitor<'de>,
220 {
221 if self.escaped {
222 match unescape(self.content.as_str())? {
223 Cow::Borrowed(_) => self.content.deserialize_item(visitor),
224 Cow::Owned(s) => visitor.visit_string(s),
225 }
226 } else {
227 self.content.deserialize_item(visitor)
228 }
229 }
230
231 fn deserialize_string<V>(self, visitor: V) -> Result<V::Value, Self::Error>
232 where
233 V: Visitor<'de>,
234 {
235 self.deserialize_str(visitor)
236 }
237
238 fn deserialize_option<V>(self, visitor: V) -> Result<V::Value, Self::Error>
241 where
242 V: Visitor<'de>,
243 {
244 if self.content.as_str().is_empty() {
245 visitor.visit_none()
246 } else {
247 visitor.visit_some(self)
248 }
249 }
250
251 fn deserialize_unit<V>(self, visitor: V) -> Result<V::Value, Self::Error>
252 where
253 V: Visitor<'de>,
254 {
255 visitor.visit_unit()
256 }
257
258 fn deserialize_unit_struct<V>(
260 self,
261 _name: &'static str,
262 visitor: V,
263 ) -> Result<V::Value, Self::Error>
264 where
265 V: Visitor<'de>,
266 {
267 self.deserialize_unit(visitor)
268 }
269
270 fn deserialize_newtype_struct<V>(
271 self,
272 _name: &'static str,
273 visitor: V,
274 ) -> Result<V::Value, Self::Error>
275 where
276 V: Visitor<'de>,
277 {
278 visitor.visit_newtype_struct(self)
279 }
280
281 fn deserialize_enum<V>(
282 self,
283 _name: &'static str,
284 _variants: &'static [&'static str],
285 visitor: V,
286 ) -> Result<V::Value, Self::Error>
287 where
288 V: Visitor<'de>,
289 {
290 visitor.visit_enum(self)
291 }
292
293 fn deserialize_identifier<V>(self, visitor: V) -> Result<V::Value, Self::Error>
295 where
296 V: Visitor<'de>,
297 {
298 self.deserialize_str(visitor)
299 }
300
301 fn deserialize_ignored_any<V>(self, visitor: V) -> Result<V::Value, Self::Error>
302 where
303 V: Visitor<'de>,
304 {
305 visitor.visit_unit()
306 }
307
308 unsupported!(deserialize_bytes => "byte arrays are not supported as `xs:list` items");
309 unsupported!(deserialize_byte_buf => "byte arrays are not supported as `xs:list` items");
310 unsupported!(deserialize_seq => "sequences are not supported as `xs:list` items");
311 unsupported!(deserialize_tuple(usize) => "tuples are not supported as `xs:list` items");
312 unsupported!(deserialize_tuple_struct(&'static str, usize) => "tuples are not supported as `xs:list` items");
313 unsupported!(deserialize_map => "maps are not supported as `xs:list` items");
314 unsupported!(deserialize_struct(&'static str, &'static [&'static str]) => "structures are not supported as `xs:list` items");
315}
316
317impl<'de, 'a> EnumAccess<'de> for AtomicDeserializer<'de, 'a> {
318 type Error = DeError;
319 type Variant = AtomicUnitOnly;
320
321 fn variant_seed<V>(self, seed: V) -> Result<(V::Value, Self::Variant), DeError>
322 where
323 V: DeserializeSeed<'de>,
324 {
325 let name = seed.deserialize(self)?;
326 Ok((name, AtomicUnitOnly))
327 }
328}
329
330pub struct AtomicUnitOnly;
336impl<'de> VariantAccess<'de> for AtomicUnitOnly {
337 type Error = DeError;
338
339 #[inline]
340 fn unit_variant(self) -> Result<(), DeError> {
341 Ok(())
342 }
343
344 fn newtype_variant_seed<T>(self, _seed: T) -> Result<T::Value, DeError>
345 where
346 T: DeserializeSeed<'de>,
347 {
348 Err(DeError::Unsupported(
349 "enum newtype variants are not supported as `xs:list` items".into(),
350 ))
351 }
352
353 fn tuple_variant<V>(self, _len: usize, _visitor: V) -> Result<V::Value, DeError>
354 where
355 V: Visitor<'de>,
356 {
357 Err(DeError::Unsupported(
358 "enum tuple variants are not supported as `xs:list` items".into(),
359 ))
360 }
361
362 fn struct_variant<V>(
363 self,
364 _fields: &'static [&'static str],
365 _visitor: V,
366 ) -> Result<V::Value, DeError>
367 where
368 V: Visitor<'de>,
369 {
370 Err(DeError::Unsupported(
371 "enum struct variants are not supported as `xs:list` items".into(),
372 ))
373 }
374}
375
376struct ListIter<'de, 'a> {
382 content: Option<Content<'de, 'a>>,
384 escaped: bool,
386}
387impl<'de, 'a> SeqAccess<'de> for ListIter<'de, 'a> {
388 type Error = DeError;
389
390 fn next_element_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>, DeError>
391 where
392 T: DeserializeSeed<'de>,
393 {
394 if let Some(mut content) = self.content.take() {
395 const DELIMITER: u8 = b' ';
396
397 loop {
398 let string = content.as_str();
399 if string.is_empty() {
400 return Ok(None);
401 }
402 return match memchr(DELIMITER, string.as_bytes()) {
403 None => seed.deserialize(AtomicDeserializer {
405 content,
406 escaped: self.escaped,
407 }),
408 Some(0) => {
410 let start = string.as_bytes().iter().position(|ch| *ch != DELIMITER);
412 content = match (start, content) {
413 (None, _) => return Ok(None),
415 (Some(start), Content::Input(s)) => Content::Input(s.split_at(start).1),
417 (Some(start), Content::Slice(s)) => Content::Slice(s.split_at(start).1),
418 (Some(start), Content::Owned(s, skip)) => {
420 Content::Owned(s, skip + start)
421 }
422 };
423 continue;
424 }
425 Some(end) => match content {
427 Content::Input(s) => {
430 let (item, rest) = s.split_at(end);
431 self.content = Some(Content::Input(rest));
432
433 seed.deserialize(AtomicDeserializer {
434 content: Content::Input(item),
435 escaped: self.escaped,
436 })
437 }
438 Content::Slice(s) => {
439 let (item, rest) = s.split_at(end);
440 self.content = Some(Content::Slice(rest));
441
442 seed.deserialize(AtomicDeserializer {
443 content: Content::Slice(item),
444 escaped: self.escaped,
445 })
446 }
447 Content::Owned(s, skip) => {
450 let item = s.split_at(skip + end).0;
451 let result = seed.deserialize(AtomicDeserializer {
452 content: Content::Slice(item),
453 escaped: self.escaped,
454 });
455
456 self.content = Some(Content::Owned(s, skip + end));
457
458 result
459 }
460 },
461 }
462 .map(Some);
463 }
464 }
465 Ok(None)
466 }
467}
468
469pub struct SimpleTypeDeserializer<'de, 'a> {
511 content: CowRef<'de, 'a, [u8]>,
514 escaped: bool,
516 decoder: Decoder,
519}
520
521impl<'de, 'a> SimpleTypeDeserializer<'de, 'a> {
522 pub fn from_text(text: Cow<'de, str>) -> Self {
524 let content = match text {
525 Cow::Borrowed(slice) => CowRef::Input(slice.as_bytes()),
526 Cow::Owned(content) => CowRef::Owned(content.into_bytes()),
527 };
528 Self::new(content, false, Decoder::utf8())
529 }
530 pub fn from_text_content(value: Text<'de>) -> Self {
532 Self::from_text(value.text)
533 }
534
535 #[allow(clippy::ptr_arg)]
537 pub fn from_part(
538 value: &'a Cow<'de, [u8]>,
539 range: Range<usize>,
540 escaped: bool,
541 decoder: Decoder,
542 ) -> Self {
543 let content = match value {
544 Cow::Borrowed(slice) => CowRef::Input(&slice[range]),
545 Cow::Owned(slice) => CowRef::Slice(&slice[range]),
546 };
547 Self::new(content, escaped, decoder)
548 }
549
550 #[inline]
552 fn new(content: CowRef<'de, 'a, [u8]>, escaped: bool, decoder: Decoder) -> Self {
553 Self {
554 content,
555 escaped,
556 decoder,
557 }
558 }
559
560 #[inline]
563 fn decode<'b>(&'b self) -> Result<Content<'de, 'b>, DeError> {
564 Ok(match self.content {
565 CowRef::Input(content) => match self.decoder.decode(content)? {
566 Cow::Borrowed(content) => Content::Input(content),
567 Cow::Owned(content) => Content::Owned(content, 0),
568 },
569 CowRef::Slice(content) => match self.decoder.decode(content)? {
570 Cow::Borrowed(content) => Content::Slice(content),
571 Cow::Owned(content) => Content::Owned(content, 0),
572 },
573 CowRef::Owned(ref content) => match self.decoder.decode(content)? {
574 Cow::Borrowed(content) => Content::Slice(content),
575 Cow::Owned(content) => Content::Owned(content, 0),
576 },
577 })
578 }
579}
580
581impl<'de, 'a> Deserializer<'de> for SimpleTypeDeserializer<'de, 'a> {
582 type Error = DeError;
583
584 fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Self::Error>
586 where
587 V: Visitor<'de>,
588 {
589 self.deserialize_str(visitor)
590 }
591
592 fn deserialize_bool<V>(self, visitor: V) -> Result<V::Value, Self::Error>
593 where
594 V: Visitor<'de>,
595 {
596 deserialize_bool(&self.content, self.decoder, visitor)
597 }
598
599 deserialize_num!(deserialize_i8 => visit_i8);
600 deserialize_num!(deserialize_i16 => visit_i16);
601 deserialize_num!(deserialize_i32 => visit_i32);
602 deserialize_num!(deserialize_i64 => visit_i64);
603
604 deserialize_num!(deserialize_u8 => visit_u8);
605 deserialize_num!(deserialize_u16 => visit_u16);
606 deserialize_num!(deserialize_u32 => visit_u32);
607 deserialize_num!(deserialize_u64 => visit_u64);
608
609 serde_if_integer128! {
610 deserialize_num!(deserialize_i128 => visit_i128);
611 deserialize_num!(deserialize_u128 => visit_u128);
612 }
613
614 deserialize_num!(deserialize_f32 => visit_f32);
615 deserialize_num!(deserialize_f64 => visit_f64);
616
617 fn deserialize_char<V>(self, visitor: V) -> Result<V::Value, Self::Error>
619 where
620 V: Visitor<'de>,
621 {
622 self.deserialize_str(visitor)
623 }
624
625 fn deserialize_str<V>(self, visitor: V) -> Result<V::Value, Self::Error>
626 where
627 V: Visitor<'de>,
628 {
629 let content = self.decode()?;
630 if self.escaped {
631 match unescape(content.as_str())? {
632 Cow::Borrowed(_) => content.deserialize_all(visitor),
633 Cow::Owned(s) => visitor.visit_string(s),
634 }
635 } else {
636 content.deserialize_all(visitor)
637 }
638 }
639
640 fn deserialize_string<V>(self, visitor: V) -> Result<V::Value, Self::Error>
642 where
643 V: Visitor<'de>,
644 {
645 self.deserialize_str(visitor)
646 }
647
648 fn deserialize_bytes<V>(self, _visitor: V) -> Result<V::Value, Self::Error>
650 where
651 V: Visitor<'de>,
652 {
653 Err(DeError::Unsupported(
654 "binary data content is not supported by XML format".into(),
655 ))
656 }
657
658 fn deserialize_byte_buf<V>(self, visitor: V) -> Result<V::Value, Self::Error>
660 where
661 V: Visitor<'de>,
662 {
663 self.deserialize_bytes(visitor)
664 }
665
666 fn deserialize_option<V>(self, visitor: V) -> Result<V::Value, Self::Error>
667 where
668 V: Visitor<'de>,
669 {
670 visitor.visit_some(self)
671 }
672
673 fn deserialize_unit<V>(self, visitor: V) -> Result<V::Value, Self::Error>
674 where
675 V: Visitor<'de>,
676 {
677 visitor.visit_unit()
678 }
679
680 fn deserialize_unit_struct<V>(
682 self,
683 _name: &'static str,
684 visitor: V,
685 ) -> Result<V::Value, Self::Error>
686 where
687 V: Visitor<'de>,
688 {
689 self.deserialize_unit(visitor)
690 }
691
692 fn deserialize_newtype_struct<V>(
693 self,
694 _name: &'static str,
695 visitor: V,
696 ) -> Result<V::Value, Self::Error>
697 where
698 V: Visitor<'de>,
699 {
700 visitor.visit_newtype_struct(self)
701 }
702
703 fn deserialize_seq<V>(self, visitor: V) -> Result<V::Value, Self::Error>
704 where
705 V: Visitor<'de>,
706 {
707 visitor.visit_seq(ListIter {
708 content: Some(self.decode()?),
709 escaped: self.escaped,
710 })
711 }
712
713 fn deserialize_tuple<V>(self, _len: usize, visitor: V) -> Result<V::Value, Self::Error>
715 where
716 V: Visitor<'de>,
717 {
718 self.deserialize_seq(visitor)
719 }
720
721 fn deserialize_tuple_struct<V>(
723 self,
724 _name: &'static str,
725 len: usize,
726 visitor: V,
727 ) -> Result<V::Value, DeError>
728 where
729 V: Visitor<'de>,
730 {
731 self.deserialize_tuple(len, visitor)
732 }
733
734 unsupported!(deserialize_map => "maps are not supported for XSD `simpleType`s");
735 unsupported!(deserialize_struct(&'static str, &'static [&'static str])
736 => "structures are not supported for XSD `simpleType`s");
737
738 fn deserialize_enum<V>(
739 self,
740 _name: &'static str,
741 _variants: &'static [&'static str],
742 visitor: V,
743 ) -> Result<V::Value, Self::Error>
744 where
745 V: Visitor<'de>,
746 {
747 visitor.visit_enum(self)
748 }
749
750 fn deserialize_identifier<V>(self, visitor: V) -> Result<V::Value, Self::Error>
752 where
753 V: Visitor<'de>,
754 {
755 self.deserialize_str(visitor)
756 }
757
758 fn deserialize_ignored_any<V>(self, visitor: V) -> Result<V::Value, Self::Error>
759 where
760 V: Visitor<'de>,
761 {
762 visitor.visit_unit()
763 }
764}
765
766impl<'de, 'a> EnumAccess<'de> for SimpleTypeDeserializer<'de, 'a> {
767 type Error = DeError;
768 type Variant = SimpleTypeUnitOnly;
769
770 fn variant_seed<V>(self, seed: V) -> Result<(V::Value, Self::Variant), DeError>
771 where
772 V: DeserializeSeed<'de>,
773 {
774 let name = seed.deserialize(self)?;
775 Ok((name, SimpleTypeUnitOnly))
776 }
777}
778
779pub struct SimpleTypeUnitOnly;
785impl<'de> VariantAccess<'de> for SimpleTypeUnitOnly {
786 type Error = DeError;
787
788 #[inline]
789 fn unit_variant(self) -> Result<(), DeError> {
790 Ok(())
791 }
792
793 fn newtype_variant_seed<T>(self, _seed: T) -> Result<T::Value, DeError>
794 where
795 T: DeserializeSeed<'de>,
796 {
797 Err(DeError::Unsupported(
798 "enum newtype variants are not supported for XSD `simpleType`s".into(),
799 ))
800 }
801
802 fn tuple_variant<V>(self, _len: usize, _visitor: V) -> Result<V::Value, DeError>
803 where
804 V: Visitor<'de>,
805 {
806 Err(DeError::Unsupported(
807 "enum tuple variants are not supported for XSD `simpleType`s".into(),
808 ))
809 }
810
811 fn struct_variant<V>(
812 self,
813 _fields: &'static [&'static str],
814 _visitor: V,
815 ) -> Result<V::Value, DeError>
816 where
817 V: Visitor<'de>,
818 {
819 Err(DeError::Unsupported(
820 "enum struct variants are not supported for XSD `simpleType`s".into(),
821 ))
822 }
823}
824
825#[cfg(test)]
828mod tests {
829 use super::*;
830 use crate::se::simple_type::{QuoteTarget, SimpleTypeSerializer};
831 use crate::se::{Indent, QuoteLevel};
832 use crate::utils::{ByteBuf, Bytes};
833 use serde::de::IgnoredAny;
834 use serde::{Deserialize, Serialize};
835 use std::collections::HashMap;
836
837 macro_rules! simple_only {
838 ($encoding:ident, $name:ident: $type:ty = $xml:expr => $result:expr) => {
839 #[test]
840 fn $name() {
841 let decoder = Decoder::$encoding();
842 let xml = $xml;
843 let de = SimpleTypeDeserializer::new(CowRef::Input(xml.as_ref()), true, decoder);
844 let data: $type = Deserialize::deserialize(de).unwrap();
845
846 assert_eq!(data, $result);
847 }
848 };
849 }
850
851 macro_rules! simple {
852 ($encoding:ident, $name:ident: $type:ty = $xml:expr => $result:expr) => {
853 #[test]
854 fn $name() {
855 let decoder = Decoder::$encoding();
856 let xml = $xml;
857 let de = SimpleTypeDeserializer::new(CowRef::Input(xml.as_ref()), true, decoder);
858 let data: $type = Deserialize::deserialize(de).unwrap();
859
860 assert_eq!(data, $result);
861
862 assert_eq!(
864 data.serialize(SimpleTypeSerializer {
865 writer: String::new(),
866 target: QuoteTarget::Text,
867 level: QuoteLevel::Full,
868 indent: Indent::None,
869 })
870 .unwrap(),
871 xml
872 );
873 }
874 };
875 }
876
877 macro_rules! err {
878 ($encoding:ident, $name:ident: $type:ty = $xml:expr => $kind:ident($reason:literal)) => {
879 #[test]
880 fn $name() {
881 let decoder = Decoder::$encoding();
882 let xml = $xml;
883 let de = SimpleTypeDeserializer::new(CowRef::Input(xml.as_ref()), true, decoder);
884 let err = <$type as Deserialize>::deserialize(de).unwrap_err();
885
886 match err {
887 DeError::$kind(e) => assert_eq!(e, $reason),
888 _ => panic!(
889 "Expected `{}({})`, found `{:?}`",
890 stringify!($kind),
891 $reason,
892 err
893 ),
894 }
895 }
896 };
897 }
898
899 #[derive(Debug, Deserialize, Serialize, PartialEq)]
900 struct Unit;
901
902 #[derive(Debug, Deserialize, Serialize, PartialEq)]
903 struct Newtype(String);
904
905 #[derive(Debug, Deserialize, Serialize, PartialEq)]
906 struct Tuple((), ());
907
908 #[derive(Debug, Deserialize, Serialize, PartialEq)]
909 struct BorrowedNewtype<'a>(&'a str);
910
911 #[derive(Debug, Deserialize, Serialize, PartialEq)]
912 struct Struct {
913 key: String,
914 val: usize,
915 }
916
917 #[derive(Debug, Deserialize, Serialize, PartialEq)]
918 enum Enum {
919 Unit,
920 Newtype(String),
921 Tuple(String, usize),
922 Struct { key: String, val: usize },
923 }
924
925 #[derive(Debug, Deserialize, PartialEq)]
926 #[serde(field_identifier)]
927 enum Id {
928 Field,
929 }
930
931 #[derive(Debug, Deserialize)]
932 #[serde(transparent)]
933 struct Any(IgnoredAny);
934 impl PartialEq for Any {
935 fn eq(&self, _other: &Any) -> bool {
936 true
937 }
938 }
939
940 mod atomic {
942 use super::*;
943 use crate::se::simple_type::AtomicSerializer;
944 use pretty_assertions::assert_eq;
945
946 macro_rules! deserialized_to_only {
948 ($name:ident: $type:ty = $input:literal => $result:expr) => {
949 #[test]
950 fn $name() {
951 let de = AtomicDeserializer {
952 content: Content::Input($input),
953 escaped: true,
954 };
955 let data: $type = Deserialize::deserialize(de).unwrap();
956
957 assert_eq!(data, $result);
958 }
959 };
960 }
961
962 macro_rules! deserialized_to {
965 ($name:ident: $type:ty = $input:literal => $result:expr) => {
966 #[test]
967 fn $name() {
968 let de = AtomicDeserializer {
969 content: Content::Input($input),
970 escaped: true,
971 };
972 let data: $type = Deserialize::deserialize(de).unwrap();
973
974 assert_eq!(data, $result);
975
976 let mut buffer = String::new();
978 let has_written = data
979 .serialize(AtomicSerializer {
980 writer: &mut buffer,
981 target: QuoteTarget::Text,
982 level: QuoteLevel::Full,
983 indent: Some(Indent::None),
984 })
985 .unwrap();
986 assert_eq!(buffer, $input);
987 assert_eq!(has_written, !buffer.is_empty());
988 }
989 };
990 }
991
992 macro_rules! err {
995 ($name:ident: $type:ty = $input:literal => $kind:ident($reason:literal)) => {
996 #[test]
997 fn $name() {
998 let de = AtomicDeserializer {
999 content: Content::Input($input),
1000 escaped: true,
1001 };
1002 let err = <$type as Deserialize>::deserialize(de).unwrap_err();
1003
1004 match err {
1005 DeError::$kind(e) => assert_eq!(e, $reason),
1006 _ => panic!(
1007 "Expected `{}({})`, found `{:?}`",
1008 stringify!($kind),
1009 $reason,
1010 err
1011 ),
1012 }
1013 }
1014 };
1015 }
1016
1017 deserialized_to!(false_: bool = "false" => false);
1018 deserialized_to!(true_: bool = "true" => true);
1019
1020 deserialized_to!(i8_: i8 = "-2" => -2);
1021 deserialized_to!(i16_: i16 = "-2" => -2);
1022 deserialized_to!(i32_: i32 = "-2" => -2);
1023 deserialized_to!(i64_: i64 = "-2" => -2);
1024
1025 deserialized_to!(u8_: u8 = "3" => 3);
1026 deserialized_to!(u16_: u16 = "3" => 3);
1027 deserialized_to!(u32_: u32 = "3" => 3);
1028 deserialized_to!(u64_: u64 = "3" => 3);
1029
1030 serde_if_integer128! {
1031 deserialized_to!(i128_: i128 = "-2" => -2);
1032 deserialized_to!(u128_: u128 = "2" => 2);
1033 }
1034
1035 deserialized_to!(f32_: f32 = "1.23" => 1.23);
1036 deserialized_to!(f64_: f64 = "1.23" => 1.23);
1037
1038 deserialized_to!(char_unescaped: char = "h" => 'h');
1039 deserialized_to!(char_escaped: char = "<" => '<');
1040
1041 deserialized_to!(string: String = "<escaped string" => "<escaped string");
1042 deserialized_to_only!(borrowed_str: &str = "non-escaped string" => "non-escaped string");
1045 err!(escaped_str: &str = "escaped string"
1046 => Custom("invalid type: string \"escaped string\", expected a borrowed string"));
1047
1048 err!(byte_buf: ByteBuf = "<escaped string"
1049 => Unsupported("byte arrays are not supported as `xs:list` items"));
1050 err!(borrowed_bytes: Bytes = "non-escaped string"
1051 => Unsupported("byte arrays are not supported as `xs:list` items"));
1052
1053 deserialized_to!(option_none: Option<&str> = "" => None);
1054 deserialized_to!(option_some: Option<&str> = "non-escaped-string" => Some("non-escaped-string"));
1055
1056 deserialized_to_only!(unit: () = "<root>anything</root>" => ());
1057 deserialized_to_only!(unit_struct: Unit = "<root>anything</root>" => Unit);
1058
1059 deserialized_to!(newtype_owned: Newtype = "<escaped string" => Newtype("<escaped string".into()));
1060 deserialized_to_only!(newtype_borrowed: BorrowedNewtype = "non-escaped string"
1063 => BorrowedNewtype("non-escaped string"));
1064
1065 err!(seq: Vec<()> = "non-escaped string"
1066 => Unsupported("sequences are not supported as `xs:list` items"));
1067 err!(tuple: ((), ()) = "non-escaped string"
1068 => Unsupported("tuples are not supported as `xs:list` items"));
1069 err!(tuple_struct: Tuple = "non-escaped string"
1070 => Unsupported("tuples are not supported as `xs:list` items"));
1071
1072 err!(map: HashMap<(), ()> = "non-escaped string"
1073 => Unsupported("maps are not supported as `xs:list` items"));
1074 err!(struct_: Struct = "non-escaped string"
1075 => Unsupported("structures are not supported as `xs:list` items"));
1076
1077 deserialized_to!(enum_unit: Enum = "Unit" => Enum::Unit);
1078 err!(enum_newtype: Enum = "Newtype"
1079 => Unsupported("enum newtype variants are not supported as `xs:list` items"));
1080 err!(enum_tuple: Enum = "Tuple"
1081 => Unsupported("enum tuple variants are not supported as `xs:list` items"));
1082 err!(enum_struct: Enum = "Struct"
1083 => Unsupported("enum struct variants are not supported as `xs:list` items"));
1084 err!(enum_other: Enum = "any data"
1085 => Custom("unknown variant `any data`, expected one of `Unit`, `Newtype`, `Tuple`, `Struct`"));
1086
1087 deserialized_to_only!(identifier: Id = "Field" => Id::Field);
1088 deserialized_to_only!(ignored_any: Any = "any data" => Any(IgnoredAny));
1089
1090 #[test]
1092 #[cfg(feature = "encoding")]
1093 fn owned_data() {
1094 let de = AtomicDeserializer {
1095 content: Content::Owned("string slice".into(), 7),
1096 escaped: true,
1097 };
1098 assert_eq!(de.content.as_str(), "slice");
1099
1100 let data: String = Deserialize::deserialize(de).unwrap();
1101 assert_eq!(data, "slice");
1102 }
1103
1104 #[test]
1107 fn borrowed_from_deserializer() {
1108 let de = AtomicDeserializer {
1109 content: Content::Slice("string slice"),
1110 escaped: true,
1111 };
1112 assert_eq!(de.content.as_str(), "string slice");
1113
1114 let data: String = Deserialize::deserialize(de).unwrap();
1115 assert_eq!(data, "string slice");
1116 }
1117 }
1118
1119 mod list {
1121 use super::*;
1122 use pretty_assertions::assert_eq;
1123
1124 #[test]
1125 fn empty() {
1126 let mut seq = ListIter {
1127 content: Some(Content::Input("")),
1128 escaped: true,
1129 };
1130
1131 assert_eq!(seq.next_element::<&str>().unwrap(), None);
1132 assert_eq!(seq.next_element::<&str>().unwrap(), None);
1133 }
1134
1135 #[test]
1136 fn only_spaces() {
1137 let mut seq = ListIter {
1138 content: Some(Content::Input(" ")),
1139 escaped: true,
1140 };
1141
1142 assert_eq!(seq.next_element::<&str>().unwrap(), None);
1143 assert_eq!(seq.next_element::<&str>().unwrap(), None);
1144 }
1145
1146 #[test]
1147 fn one_item() {
1148 let mut seq = ListIter {
1149 content: Some(Content::Input("abc")),
1150 escaped: true,
1151 };
1152
1153 assert_eq!(seq.next_element::<&str>().unwrap(), Some("abc"));
1154 assert_eq!(seq.next_element::<&str>().unwrap(), None);
1155 assert_eq!(seq.next_element::<&str>().unwrap(), None);
1156 }
1157
1158 #[test]
1159 fn two_items() {
1160 let mut seq = ListIter {
1161 content: Some(Content::Input("abc def")),
1162 escaped: true,
1163 };
1164
1165 assert_eq!(seq.next_element::<&str>().unwrap(), Some("abc"));
1166 assert_eq!(seq.next_element::<&str>().unwrap(), Some("def"));
1167 assert_eq!(seq.next_element::<&str>().unwrap(), None);
1168 assert_eq!(seq.next_element::<&str>().unwrap(), None);
1169 }
1170
1171 #[test]
1172 fn leading_spaces() {
1173 let mut seq = ListIter {
1174 content: Some(Content::Input(" def")),
1175 escaped: true,
1176 };
1177
1178 assert_eq!(seq.next_element::<&str>().unwrap(), Some("def"));
1179 assert_eq!(seq.next_element::<&str>().unwrap(), None);
1180 assert_eq!(seq.next_element::<&str>().unwrap(), None);
1181 }
1182
1183 #[test]
1184 fn trailing_spaces() {
1185 let mut seq = ListIter {
1186 content: Some(Content::Input("abc ")),
1187 escaped: true,
1188 };
1189
1190 assert_eq!(seq.next_element::<&str>().unwrap(), Some("abc"));
1191 assert_eq!(seq.next_element::<&str>().unwrap(), None);
1192 assert_eq!(seq.next_element::<&str>().unwrap(), None);
1193 }
1194
1195 #[test]
1196 fn mixed_types() {
1197 let mut seq = ListIter {
1198 content: Some(Content::Input("string 1.23 42 true false h Unit")),
1199 escaped: true,
1200 };
1201
1202 assert_eq!(seq.next_element::<&str>().unwrap(), Some("string"));
1203 assert_eq!(seq.next_element::<f32>().unwrap(), Some(1.23));
1204 assert_eq!(seq.next_element::<u32>().unwrap(), Some(42));
1205 assert_eq!(seq.next_element::<bool>().unwrap(), Some(true));
1206 assert_eq!(seq.next_element::<bool>().unwrap(), Some(false));
1207 assert_eq!(seq.next_element::<char>().unwrap(), Some('h'));
1208 assert_eq!(seq.next_element::<Enum>().unwrap(), Some(Enum::Unit));
1209 assert_eq!(seq.next_element::<()>().unwrap(), None);
1210 assert_eq!(seq.next_element::<()>().unwrap(), None);
1211 }
1212 }
1213
1214 mod utf8 {
1215 use super::*;
1216 use pretty_assertions::assert_eq;
1217
1218 simple!(utf8, i8_: i8 = "-2" => -2);
1219 simple!(utf8, i16_: i16 = "-2" => -2);
1220 simple!(utf8, i32_: i32 = "-2" => -2);
1221 simple!(utf8, i64_: i64 = "-2" => -2);
1222
1223 simple!(utf8, u8_: u8 = "3" => 3);
1224 simple!(utf8, u16_: u16 = "3" => 3);
1225 simple!(utf8, u32_: u32 = "3" => 3);
1226 simple!(utf8, u64_: u64 = "3" => 3);
1227
1228 serde_if_integer128! {
1229 simple!(utf8, i128_: i128 = "-2" => -2);
1230 simple!(utf8, u128_: u128 = "2" => 2);
1231 }
1232
1233 simple!(utf8, f32_: f32 = "1.23" => 1.23);
1234 simple!(utf8, f64_: f64 = "1.23" => 1.23);
1235
1236 simple!(utf8, false_: bool = "false" => false);
1237 simple!(utf8, true_: bool = "true" => true);
1238 simple!(utf8, char_unescaped: char = "h" => 'h');
1239 simple!(utf8, char_escaped: char = "<" => '<');
1240
1241 simple!(utf8, string: String = "<escaped string" => "<escaped string");
1242 err!(utf8, byte_buf: ByteBuf = "<escaped string"
1243 => Unsupported("binary data content is not supported by XML format"));
1244
1245 simple!(utf8, borrowed_str: &str = "non-escaped string" => "non-escaped string");
1246 err!(utf8, borrowed_bytes: Bytes = "<escaped string"
1247 => Unsupported("binary data content is not supported by XML format"));
1248
1249 simple!(utf8, option_none: Option<&str> = "" => Some(""));
1250 simple!(utf8, option_some: Option<&str> = "non-escaped string" => Some("non-escaped string"));
1251
1252 simple_only!(utf8, unit: () = "any data" => ());
1253 simple_only!(utf8, unit_struct: Unit = "any data" => Unit);
1254
1255 simple_only!(utf8, newtype_owned: Newtype = "<escaped string"
1260 => Newtype("<escaped string".into()));
1261 simple_only!(utf8, newtype_borrowed: BorrowedNewtype = "non-escaped string"
1262 => BorrowedNewtype("non-escaped string"));
1263
1264 err!(utf8, map: HashMap<(), ()> = "any data"
1265 => Unsupported("maps are not supported for XSD `simpleType`s"));
1266 err!(utf8, struct_: Struct = "any data"
1267 => Unsupported("structures are not supported for XSD `simpleType`s"));
1268
1269 simple!(utf8, enum_unit: Enum = "Unit" => Enum::Unit);
1270 err!(utf8, enum_newtype: Enum = "Newtype"
1271 => Unsupported("enum newtype variants are not supported for XSD `simpleType`s"));
1272 err!(utf8, enum_tuple: Enum = "Tuple"
1273 => Unsupported("enum tuple variants are not supported for XSD `simpleType`s"));
1274 err!(utf8, enum_struct: Enum = "Struct"
1275 => Unsupported("enum struct variants are not supported for XSD `simpleType`s"));
1276 err!(utf8, enum_other: Enum = "any data"
1277 => Custom("unknown variant `any data`, expected one of `Unit`, `Newtype`, `Tuple`, `Struct`"));
1278
1279 simple_only!(utf8, identifier: Id = "Field" => Id::Field);
1280 simple_only!(utf8, ignored_any: Any = "any data" => Any(IgnoredAny));
1281 }
1282
1283 #[cfg(feature = "encoding")]
1284 mod utf16 {
1285 use super::*;
1286 use pretty_assertions::assert_eq;
1287
1288 fn to_utf16(string: &str) -> Vec<u8> {
1289 let mut bytes = Vec::new();
1290 for ch in string.encode_utf16() {
1291 bytes.extend_from_slice(&ch.to_le_bytes());
1292 }
1293 bytes
1294 }
1295
1296 macro_rules! utf16 {
1297 ($name:ident: $type:ty = $xml:literal => $result:expr) => {
1298 simple_only!(utf16, $name: $type = to_utf16($xml) => $result);
1299 };
1300 }
1301
1302 macro_rules! unsupported {
1303 ($name:ident: $type:ty = $xml:literal => $err:literal) => {
1304 err!(utf16, $name: $type = to_utf16($xml) => Unsupported($err));
1305 };
1306 }
1307
1308 utf16!(i8_: i8 = "-2" => -2);
1309 utf16!(i16_: i16 = "-2" => -2);
1310 utf16!(i32_: i32 = "-2" => -2);
1311 utf16!(i64_: i64 = "-2" => -2);
1312
1313 utf16!(u8_: u8 = "3" => 3);
1314 utf16!(u16_: u16 = "3" => 3);
1315 utf16!(u32_: u32 = "3" => 3);
1316 utf16!(u64_: u64 = "3" => 3);
1317
1318 serde_if_integer128! {
1319 utf16!(i128_: i128 = "-2" => -2);
1320 utf16!(u128_: u128 = "2" => 2);
1321 }
1322
1323 utf16!(f32_: f32 = "1.23" => 1.23);
1324 utf16!(f64_: f64 = "1.23" => 1.23);
1325
1326 utf16!(false_: bool = "false" => false);
1327 utf16!(true_: bool = "true" => true);
1328 utf16!(char_unescaped: char = "h" => 'h');
1329 utf16!(char_escaped: char = "<" => '<');
1330
1331 utf16!(string: String = "<escaped string" => "<escaped string");
1332 unsupported!(borrowed_bytes: Bytes = "<escaped string"
1333 => "binary data content is not supported by XML format");
1334
1335 utf16!(option_none: Option<()> = "" => Some(()));
1336 utf16!(option_some: Option<()> = "any data" => Some(()));
1337
1338 utf16!(unit: () = "any data" => ());
1339 utf16!(unit_struct: Unit = "any data" => Unit);
1340
1341 utf16!(newtype_owned: Newtype = "<escaped string" => Newtype("<escaped string".into()));
1342
1343 err!(utf16, newtype_borrowed: BorrowedNewtype = to_utf16("non-escaped string")
1345 => Custom("invalid type: string \"non-escaped string\", expected a borrowed string"));
1346
1347 unsupported!(map: HashMap<(), ()> = "any data"
1348 => "maps are not supported for XSD `simpleType`s");
1349 unsupported!(struct_: Struct = "any data"
1350 => "structures are not supported for XSD `simpleType`s");
1351
1352 utf16!(enum_unit: Enum = "Unit" => Enum::Unit);
1353 unsupported!(enum_newtype: Enum = "Newtype"
1354 => "enum newtype variants are not supported for XSD `simpleType`s");
1355 unsupported!(enum_tuple: Enum = "Tuple"
1356 => "enum tuple variants are not supported for XSD `simpleType`s");
1357 unsupported!(enum_struct: Enum = "Struct"
1358 => "enum struct variants are not supported for XSD `simpleType`s");
1359 err!(utf16, enum_other: Enum = to_utf16("any data")
1360 => Custom("unknown variant `any data`, expected one of `Unit`, `Newtype`, `Tuple`, `Struct`"));
1361
1362 utf16!(identifier: Id = "Field" => Id::Field);
1363 utf16!(ignored_any: Any = "any data" => Any(IgnoredAny));
1364 }
1365}