1 //! Serde `Deserializer` module
2 //!
3 //! # Examples
4 //!
5 //! Here is a simple example parsing [crates.io](https://crates.io/) source code.
6 //!
7 //! ```
8 //! // Cargo.toml
9 //! // [dependencies]
10 //! // serde = { version = "1.0", features = [ "derive" ] }
11 //! // quick-xml = { version = "0.21", features = [ "serialize" ] }
12 //! extern crate serde;
13 //! extern crate quick_xml;
14 //!
15 //! use serde::Deserialize;
16 //! use quick_xml::de::{from_str, DeError};
17 //!
18 //! #[derive(Debug, Deserialize, PartialEq)]
19 //! struct Link {
20 //!     rel: String,
21 //!     href: String,
22 //!     sizes: Option<String>,
23 //! }
24 //!
25 //! #[derive(Debug, Deserialize, PartialEq)]
26 //! #[serde(rename_all = "lowercase")]
27 //! enum Lang {
28 //!     En,
29 //!     Fr,
30 //!     De,
31 //! }
32 //!
33 //! #[derive(Debug, Deserialize, PartialEq)]
34 //! struct Head {
35 //!     title: String,
36 //!     #[serde(rename = "link", default)]
37 //!     links: Vec<Link>,
38 //! }
39 //!
40 //! #[derive(Debug, Deserialize, PartialEq)]
41 //! struct Script {
42 //!     src: String,
43 //!     integrity: String,
44 //! }
45 //!
46 //! #[derive(Debug, Deserialize, PartialEq)]
47 //! struct Body {
48 //!     #[serde(rename = "script", default)]
49 //!     scripts: Vec<Script>,
50 //! }
51 //!
52 //! #[derive(Debug, Deserialize, PartialEq)]
53 //! struct Html {
54 //!     lang: Option<String>,
55 //!     head: Head,
56 //!     body: Body,
57 //! }
58 //!
59 //! fn crates_io() -> Result<Html, DeError> {
60 //!     let xml = "<!DOCTYPE html>
61 //!         <html lang=\"en\">
62 //!           <head>
63 //!             <meta charset=\"utf-8\">
64 //!             <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\">
65 //!             <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">
66 //!
67 //!             <title>crates.io: Rust Package Registry</title>
68 //!
69 //!
70 //!         <meta name=\"cargo/config/environment\" content=\"%7B%22modulePrefix%22%3A%22cargo%22%2C%22environment%22%3A%22production%22%2C%22rootURL%22%3A%22%2F%22%2C%22locationType%22%3A%22router-scroll%22%2C%22historySupportMiddleware%22%3Atrue%2C%22EmberENV%22%3A%7B%22FEATURES%22%3A%7B%7D%2C%22EXTEND_PROTOTYPES%22%3A%7B%22Date%22%3Afalse%7D%7D%2C%22APP%22%3A%7B%22name%22%3A%22cargo%22%2C%22version%22%3A%22b7796c9%22%7D%2C%22fastboot%22%3A%7B%22hostWhitelist%22%3A%5B%22crates.io%22%2C%7B%7D%2C%7B%7D%5D%7D%2C%22ember-cli-app-version%22%3A%7B%22version%22%3A%22b7796c9%22%7D%2C%22ember-cli-mirage%22%3A%7B%22usingProxy%22%3Afalse%2C%22useDefaultPassthroughs%22%3Atrue%7D%2C%22exportApplicationGlobal%22%3Afalse%7D\" />
71 //!         <!-- EMBER_CLI_FASTBOOT_TITLE --><!-- EMBER_CLI_FASTBOOT_HEAD -->
72 //!         <link rel=\"manifest\" href=\"/manifest.webmanifest\">
73 //!         <link rel=\"apple-touch-icon\" href=\"/cargo-835dd6a18132048a52ac569f2615b59d.png\" sizes=\"227x227\">
74 //!         <meta name=\"theme-color\" content=\"#f9f7ec\">
75 //!         <meta name=\"apple-mobile-web-app-capable\" content=\"yes\">
76 //!         <meta name=\"apple-mobile-web-app-title\" content=\"crates.io: Rust Package Registry\">
77 //!         <meta name=\"apple-mobile-web-app-status-bar-style\" content=\"default\">
78 //!
79 //!             <link rel=\"stylesheet\" href=\"/assets/vendor-8d023d47762d5431764f589a6012123e.css\" integrity=\"sha256-EoB7fsYkdS7BZba47+C/9D7yxwPZojsE4pO7RIuUXdE= sha512-/SzGQGR0yj5AG6YPehZB3b6MjpnuNCTOGREQTStETobVRrpYPZKneJwcL/14B8ufcvobJGFDvnTKdcDDxbh6/A==\" >
80 //!             <link rel=\"stylesheet\" href=\"/assets/cargo-cedb8082b232ce89dd449d869fb54b98.css\" integrity=\"sha256-S9K9jZr6nSyYicYad3JdiTKrvsstXZrvYqmLUX9i3tc= sha512-CDGjy3xeyiqBgUMa+GelihW394pqAARXwsU+HIiOotlnp1sLBVgO6v2ZszL0arwKU8CpvL9wHyLYBIdfX92YbQ==\" >
81 //!
82 //!
83 //!             <link rel=\"shortcut icon\" href=\"/favicon.ico\" type=\"image/x-icon\">
84 //!             <link rel=\"icon\" href=\"/cargo-835dd6a18132048a52ac569f2615b59d.png\" type=\"image/png\">
85 //!             <link rel=\"search\" href=\"/opensearch.xml\" type=\"application/opensearchdescription+xml\" title=\"Cargo\">
86 //!           </head>
87 //!           <body>
88 //!             <!-- EMBER_CLI_FASTBOOT_BODY -->
89 //!             <noscript>
90 //!                 <div id=\"main\">
91 //!                     <div class='noscript'>
92 //!                         This site requires JavaScript to be enabled.
93 //!                     </div>
94 //!                 </div>
95 //!             </noscript>
96 //!
97 //!             <script src=\"/assets/vendor-bfe89101b20262535de5a5ccdc276965.js\" integrity=\"sha256-U12Xuwhz1bhJXWyFW/hRr+Wa8B6FFDheTowik5VLkbw= sha512-J/cUUuUN55TrdG8P6Zk3/slI0nTgzYb8pOQlrXfaLgzr9aEumr9D1EzmFyLy1nrhaDGpRN1T8EQrU21Jl81pJQ==\" ></script>
98 //!             <script src=\"/assets/cargo-4023b68501b7b3e17b2bb31f50f5eeea.js\" integrity=\"sha256-9atimKc1KC6HMJF/B07lP3Cjtgr2tmET8Vau0Re5mVI= sha512-XJyBDQU4wtA1aPyPXaFzTE5Wh/mYJwkKHqZ/Fn4p/ezgdKzSCFu6FYn81raBCnCBNsihfhrkb88uF6H5VraHMA==\" ></script>
99 //!
100 //!
101 //!           </body>
102 //!         </html>
103 //! }";
104 //!     let html: Html = from_str(xml)?;
105 //!     assert_eq!(&html.head.title, "crates.io: Rust Package Registr");
106 //!     Ok(html)
107 //! }
108 //! ```
109 
110 mod escape;
111 mod map;
112 mod seq;
113 mod var;
114 
115 pub use crate::errors::serialize::DeError;
116 use crate::{
117     events::{BytesStart, BytesText, Event},
118     Reader,
119 };
120 use serde::de::{self, DeserializeOwned};
121 use serde::serde_if_integer128;
122 use std::io::BufRead;
123 
124 const INNER_VALUE: &str = "$value";
125 
126 /// An xml deserializer
127 pub struct Deserializer<R: BufRead> {
128     reader: Reader<R>,
129     peek: Option<Event<'static>>,
130     has_value_field: bool,
131 }
132 
133 /// Deserialize a xml string
from_str<T: DeserializeOwned>(s: &str) -> Result<T, DeError>134 pub fn from_str<T: DeserializeOwned>(s: &str) -> Result<T, DeError> {
135     from_reader(s.as_bytes())
136 }
137 
138 /// Deserialize from a reader
from_reader<R: BufRead, T: DeserializeOwned>(reader: R) -> Result<T, DeError>139 pub fn from_reader<R: BufRead, T: DeserializeOwned>(reader: R) -> Result<T, DeError> {
140     let mut de = Deserializer::from_reader(reader);
141     T::deserialize(&mut de)
142 }
143 
144 impl<R: BufRead> Deserializer<R> {
145     /// Get a new deserializer
new(reader: Reader<R>) -> Self146     pub fn new(reader: Reader<R>) -> Self {
147         Deserializer {
148             reader,
149             peek: None,
150             has_value_field: false,
151         }
152     }
153 
154     /// Get a new deserializer from a regular BufRead
from_reader(reader: R) -> Self155     pub fn from_reader(reader: R) -> Self {
156         let mut reader = Reader::from_reader(reader);
157         reader
158             .expand_empty_elements(true)
159             .check_end_names(true)
160             .trim_text(true);
161         Self::new(reader)
162     }
163 
peek(&mut self) -> Result<Option<&Event<'static>>, DeError>164     fn peek(&mut self) -> Result<Option<&Event<'static>>, DeError> {
165         if self.peek.is_none() {
166             self.peek = Some(self.next(&mut Vec::new())?);
167         }
168         Ok(self.peek.as_ref())
169     }
170 
next<'a>(&mut self, buf: &'a mut Vec<u8>) -> Result<Event<'static>, DeError>171     fn next<'a>(&mut self, buf: &'a mut Vec<u8>) -> Result<Event<'static>, DeError> {
172         if let Some(e) = self.peek.take() {
173             return Ok(e);
174         }
175         loop {
176             let e = self.reader.read_event(buf)?;
177             match e {
178                 Event::Start(_) | Event::End(_) | Event::Text(_) | Event::Eof | Event::CData(_) => {
179                     return Ok(e.into_owned())
180                 }
181                 _ => buf.clear(),
182             }
183         }
184     }
185 
next_start(&mut self, buf: &mut Vec<u8>) -> Result<Option<BytesStart<'static>>, DeError>186     fn next_start(&mut self, buf: &mut Vec<u8>) -> Result<Option<BytesStart<'static>>, DeError> {
187         loop {
188             let e = self.next(buf)?;
189             match e {
190                 Event::Start(e) => return Ok(Some(e)),
191                 Event::End(_) => return Err(DeError::End),
192                 Event::Eof => return Ok(None),
193                 _ => buf.clear(), // ignore texts
194             }
195         }
196     }
197 
198     /// Consumes an one XML element, returns associated text or empty string:
199     ///
200     /// |XML                  |Result     |Comments                    |
201     /// |---------------------|-----------|----------------------------|
202     /// |`<tag ...>text</tag>`|`text`     |Complete tag consumed       |
203     /// |`<tag/>`             |empty slice|Virtual end tag not consumed|
204     /// |`</tag>`             |empty slice|Not consumed                |
next_text<'a>(&mut self) -> Result<BytesText<'static>, DeError>205     fn next_text<'a>(&mut self) -> Result<BytesText<'static>, DeError> {
206         match self.next(&mut Vec::new())? {
207             Event::Text(e) | Event::CData(e) => Ok(e),
208             Event::Eof => Err(DeError::Eof),
209             Event::Start(e) => {
210                 // allow one nested level
211                 let inner = self.next(&mut Vec::new())?;
212                 let t = match inner {
213                     Event::Text(t) | Event::CData(t) => t,
214                     Event::Start(_) => return Err(DeError::Start),
215                     Event::End(end) if end.name() == e.name() => {
216                         return Ok(BytesText::from_escaped(&[] as &[u8]));
217                     }
218                     Event::End(_) => return Err(DeError::End),
219                     Event::Eof => return Err(DeError::Eof),
220                     _ => unreachable!(),
221                 };
222                 self.read_to_end(e.name())?;
223                 Ok(t)
224             }
225             Event::End(e) => {
226                 self.peek = Some(Event::End(e));
227                 Ok(BytesText::from_escaped(&[] as &[u8]))
228             }
229             _ => unreachable!(),
230         }
231     }
232 
read_to_end(&mut self, name: &[u8]) -> Result<(), DeError>233     fn read_to_end(&mut self, name: &[u8]) -> Result<(), DeError> {
234         let mut buf = Vec::new();
235         match self.next(&mut buf)? {
236             Event::Start(e) => self.reader.read_to_end(e.name(), &mut Vec::new())?,
237             Event::End(e) if e.name() == name => return Ok(()),
238             _ => buf.clear(),
239         }
240         Ok(self.reader.read_to_end(name, &mut buf)?)
241     }
242 }
243 
244 macro_rules! deserialize_type {
245     ($deserialize:ident => $visit:ident) => {
246         fn $deserialize<V: de::Visitor<'de>>(self, visitor: V) -> Result<V::Value, DeError> {
247             let txt = self.next_text()?;
248 
249             #[cfg(not(feature = "encoding"))]
250             let value = self.reader.decode(&*txt)?.parse()?;
251 
252             #[cfg(feature = "encoding")]
253             let value = self.reader.decode(&*txt).parse()?;
254 
255             visitor.$visit(value)
256         }
257     };
258 }
259 
260 impl<'de, 'a, R: BufRead> de::Deserializer<'de> for &'a mut Deserializer<R> {
261     type Error = DeError;
262 
deserialize_struct<V: de::Visitor<'de>>( self, _name: &'static str, fields: &'static [&'static str], visitor: V, ) -> Result<V::Value, DeError>263     fn deserialize_struct<V: de::Visitor<'de>>(
264         self,
265         _name: &'static str,
266         fields: &'static [&'static str],
267         visitor: V,
268     ) -> Result<V::Value, DeError> {
269         if let Some(e) = self.next_start(&mut Vec::new())? {
270             let name = e.name().to_vec();
271             self.has_value_field = fields.contains(&INNER_VALUE);
272             let map = map::MapAccess::new(self, e)?;
273             let value = visitor.visit_map(map)?;
274             self.has_value_field = false;
275             self.read_to_end(&name)?;
276             Ok(value)
277         } else {
278             Err(DeError::Start)
279         }
280     }
281 
282     deserialize_type!(deserialize_i8 => visit_i8);
283     deserialize_type!(deserialize_i16 => visit_i16);
284     deserialize_type!(deserialize_i32 => visit_i32);
285     deserialize_type!(deserialize_i64 => visit_i64);
286     deserialize_type!(deserialize_u8 => visit_u8);
287     deserialize_type!(deserialize_u16 => visit_u16);
288     deserialize_type!(deserialize_u32 => visit_u32);
289     deserialize_type!(deserialize_u64 => visit_u64);
290     deserialize_type!(deserialize_f32 => visit_f32);
291     deserialize_type!(deserialize_f64 => visit_f64);
292 
293     serde_if_integer128! {
294         deserialize_type!(deserialize_i128 => visit_i128);
295         deserialize_type!(deserialize_u128 => visit_u128);
296     }
297 
deserialize_bool<V: de::Visitor<'de>>(self, visitor: V) -> Result<V::Value, DeError>298     fn deserialize_bool<V: de::Visitor<'de>>(self, visitor: V) -> Result<V::Value, DeError> {
299         let txt = self.next_text()?;
300 
301         #[cfg(feature = "encoding")]
302         {
303             #[cfg(feature = "encoding")]
304             let value = self.reader.decode(&*txt);
305 
306             match value.as_ref() {
307                 "true" | "1" | "True" | "TRUE" | "t" | "Yes" | "YES" | "yes" | "y" => {
308                     visitor.visit_bool(true)
309                 }
310                 "false" | "0" | "False" | "FALSE" | "f" | "No" | "NO" | "no" | "n" => {
311                     visitor.visit_bool(false)
312                 }
313                 _ => Err(DeError::InvalidBoolean(value.into())),
314             }
315         }
316 
317         #[cfg(not(feature = "encoding"))]
318         {
319             match txt.as_ref() {
320                 b"true" | b"1" | b"True" | b"TRUE" | b"t" | b"Yes" | b"YES" | b"yes" | b"y" => {
321                     visitor.visit_bool(true)
322                 }
323                 b"false" | b"0" | b"False" | b"FALSE" | b"f" | b"No" | b"NO" | b"no" | b"n" => {
324                     visitor.visit_bool(false)
325                 }
326                 e => Err(DeError::InvalidBoolean(self.reader.decode(e)?.into())),
327             }
328         }
329     }
330 
deserialize_string<V: de::Visitor<'de>>(self, visitor: V) -> Result<V::Value, DeError>331     fn deserialize_string<V: de::Visitor<'de>>(self, visitor: V) -> Result<V::Value, DeError> {
332         let value = self.next_text()?.unescape_and_decode(&self.reader)?;
333         visitor.visit_string(value)
334     }
335 
deserialize_char<V: de::Visitor<'de>>(self, visitor: V) -> Result<V::Value, DeError>336     fn deserialize_char<V: de::Visitor<'de>>(self, visitor: V) -> Result<V::Value, DeError> {
337         self.deserialize_string(visitor)
338     }
339 
deserialize_str<V: de::Visitor<'de>>(self, visitor: V) -> Result<V::Value, DeError>340     fn deserialize_str<V: de::Visitor<'de>>(self, visitor: V) -> Result<V::Value, DeError> {
341         self.deserialize_string(visitor)
342     }
343 
deserialize_bytes<V: de::Visitor<'de>>(self, visitor: V) -> Result<V::Value, DeError>344     fn deserialize_bytes<V: de::Visitor<'de>>(self, visitor: V) -> Result<V::Value, DeError> {
345         let text = self.next_text()?;
346         let value = text.escaped();
347         visitor.visit_bytes(value)
348     }
349 
deserialize_byte_buf<V: de::Visitor<'de>>(self, visitor: V) -> Result<V::Value, DeError>350     fn deserialize_byte_buf<V: de::Visitor<'de>>(self, visitor: V) -> Result<V::Value, DeError> {
351         let text = self.next_text()?;
352         let value = text.into_inner().into_owned();
353         visitor.visit_byte_buf(value)
354     }
355 
deserialize_unit<V: de::Visitor<'de>>(self, visitor: V) -> Result<V::Value, DeError>356     fn deserialize_unit<V: de::Visitor<'de>>(self, visitor: V) -> Result<V::Value, DeError> {
357         let mut buf = Vec::new();
358         match self.next(&mut buf)? {
359             Event::Start(s) => {
360                 self.read_to_end(s.name())?;
361                 visitor.visit_unit()
362             }
363             e => Err(DeError::InvalidUnit(format!("{:?}", e))),
364         }
365     }
366 
deserialize_unit_struct<V: de::Visitor<'de>>( self, _name: &'static str, visitor: V, ) -> Result<V::Value, DeError>367     fn deserialize_unit_struct<V: de::Visitor<'de>>(
368         self,
369         _name: &'static str,
370         visitor: V,
371     ) -> Result<V::Value, DeError> {
372         self.deserialize_unit(visitor)
373     }
374 
deserialize_newtype_struct<V: de::Visitor<'de>>( self, _name: &'static str, visitor: V, ) -> Result<V::Value, DeError>375     fn deserialize_newtype_struct<V: de::Visitor<'de>>(
376         self,
377         _name: &'static str,
378         visitor: V,
379     ) -> Result<V::Value, DeError> {
380         self.deserialize_tuple(1, visitor)
381     }
382 
deserialize_tuple<V: de::Visitor<'de>>( self, len: usize, visitor: V, ) -> Result<V::Value, DeError>383     fn deserialize_tuple<V: de::Visitor<'de>>(
384         self,
385         len: usize,
386         visitor: V,
387     ) -> Result<V::Value, DeError> {
388         visitor.visit_seq(seq::SeqAccess::new(self, Some(len))?)
389     }
390 
deserialize_tuple_struct<V: de::Visitor<'de>>( self, _name: &'static str, len: usize, visitor: V, ) -> Result<V::Value, DeError>391     fn deserialize_tuple_struct<V: de::Visitor<'de>>(
392         self,
393         _name: &'static str,
394         len: usize,
395         visitor: V,
396     ) -> Result<V::Value, DeError> {
397         self.deserialize_tuple(len, visitor)
398     }
399 
deserialize_enum<V: de::Visitor<'de>>( self, _name: &'static str, _variants: &'static [&'static str], visitor: V, ) -> Result<V::Value, DeError>400     fn deserialize_enum<V: de::Visitor<'de>>(
401         self,
402         _name: &'static str,
403         _variants: &'static [&'static str],
404         visitor: V,
405     ) -> Result<V::Value, DeError> {
406         let value = visitor.visit_enum(var::EnumAccess::new(self))?;
407         Ok(value)
408     }
409 
deserialize_seq<V: de::Visitor<'de>>(self, visitor: V) -> Result<V::Value, DeError>410     fn deserialize_seq<V: de::Visitor<'de>>(self, visitor: V) -> Result<V::Value, DeError> {
411         visitor.visit_seq(seq::SeqAccess::new(self, None)?)
412     }
413 
deserialize_map<V: de::Visitor<'de>>(self, visitor: V) -> Result<V::Value, DeError>414     fn deserialize_map<V: de::Visitor<'de>>(self, visitor: V) -> Result<V::Value, DeError> {
415         self.deserialize_struct("", &[], visitor)
416     }
417 
deserialize_option<V: de::Visitor<'de>>(self, visitor: V) -> Result<V::Value, DeError>418     fn deserialize_option<V: de::Visitor<'de>>(self, visitor: V) -> Result<V::Value, DeError> {
419         match self.peek()? {
420             Some(Event::Text(t)) if t.is_empty() => visitor.visit_none(),
421             None | Some(Event::Eof) => visitor.visit_none(),
422             _ => visitor.visit_some(self),
423         }
424     }
425 
deserialize_identifier<V: de::Visitor<'de>>(self, visitor: V) -> Result<V::Value, DeError>426     fn deserialize_identifier<V: de::Visitor<'de>>(self, visitor: V) -> Result<V::Value, DeError> {
427         self.deserialize_string(visitor)
428     }
429 
deserialize_ignored_any<V: de::Visitor<'de>>(self, visitor: V) -> Result<V::Value, DeError>430     fn deserialize_ignored_any<V: de::Visitor<'de>>(self, visitor: V) -> Result<V::Value, DeError> {
431         match self.next(&mut Vec::new())? {
432             Event::Start(e) => self.read_to_end(e.name())?,
433             Event::End(_) => return Err(DeError::End),
434             _ => (),
435         }
436         visitor.visit_unit()
437     }
438 
deserialize_any<V: de::Visitor<'de>>(self, visitor: V) -> Result<V::Value, DeError>439     fn deserialize_any<V: de::Visitor<'de>>(self, visitor: V) -> Result<V::Value, DeError> {
440         match self.peek()?.ok_or(DeError::Eof)? {
441             Event::Start(_) => self.deserialize_map(visitor),
442             Event::End(_) => self.deserialize_unit(visitor),
443             _ => self.deserialize_string(visitor),
444         }
445     }
446 }
447 
448 #[cfg(test)]
449 mod tests {
450     use super::*;
451     use serde::Deserialize;
452 
453     #[derive(Debug, Deserialize, PartialEq)]
454     struct Item {
455         name: String,
456         source: String,
457     }
458 
459     #[test]
simple_struct_from_attributes()460     fn simple_struct_from_attributes() {
461         let s = r##"
462 	    <item name="hello" source="world.rs" />
463 	"##;
464 
465         let item: Item = from_str(s).unwrap();
466 
467         assert_eq!(
468             item,
469             Item {
470                 name: "hello".to_string(),
471                 source: "world.rs".to_string(),
472             }
473         );
474     }
475 
476     #[test]
multiple_roots_attributes()477     fn multiple_roots_attributes() {
478         let s = r##"
479 	    <item name="hello" source="world.rs" />
480 	    <item name="hello" source="world.rs" />
481 	"##;
482 
483         let item: Vec<Item> = from_str(s).unwrap();
484 
485         assert_eq!(
486             item,
487             vec![
488                 Item {
489                     name: "hello".to_string(),
490                     source: "world.rs".to_string(),
491                 },
492                 Item {
493                     name: "hello".to_string(),
494                     source: "world.rs".to_string(),
495                 },
496             ]
497         );
498     }
499 
500     #[test]
simple_struct_from_attribute_and_child()501     fn simple_struct_from_attribute_and_child() {
502         let s = r##"
503 	    <item name="hello">
504             <source>world.rs</source>
505             </item>
506         "##;
507 
508         let item: Item = from_str(s).unwrap();
509 
510         assert_eq!(
511             item,
512             Item {
513                 name: "hello".to_string(),
514                 source: "world.rs".to_string(),
515             }
516         );
517     }
518 
519     #[derive(Debug, Deserialize, PartialEq)]
520     struct Project {
521         name: String,
522 
523         #[serde(rename = "item", default)]
524         items: Vec<Item>,
525     }
526 
527     #[test]
nested_collection()528     fn nested_collection() {
529         let s = r##"
530 	    <project name="my_project">
531 		<item name="hello1" source="world1.rs" />
532 		<item name="hello2" source="world2.rs" />
533 	    </project>
534 	"##;
535 
536         let project: Project = from_str(s).unwrap();
537 
538         assert_eq!(
539             project,
540             Project {
541                 name: "my_project".to_string(),
542                 items: vec![
543                     Item {
544                         name: "hello1".to_string(),
545                         source: "world1.rs".to_string(),
546                     },
547                     Item {
548                         name: "hello2".to_string(),
549                         source: "world2.rs".to_string(),
550                     },
551                 ],
552             }
553         );
554     }
555 
556     #[derive(Debug, Deserialize, PartialEq)]
557     enum MyEnum {
558         A(String),
559         B { name: String, flag: bool },
560         C,
561     }
562 
563     #[derive(Debug, Deserialize, PartialEq)]
564     struct MyEnums {
565         // TODO: This should be #[serde(flatten)], but right now serde don't support flattening of sequences
566         // See https://github.com/serde-rs/serde/issues/1905
567         #[serde(rename = "$value")]
568         items: Vec<MyEnum>,
569     }
570 
571     #[test]
collection_of_enums()572     fn collection_of_enums() {
573         let s = r##"
574         <enums>
575             <A>test</A>
576             <B name="hello" flag="t" />
577             <C />
578         </enums>
579         "##;
580 
581         let project: MyEnums = from_str(s).unwrap();
582 
583         assert_eq!(
584             project,
585             MyEnums {
586                 items: vec![
587                     MyEnum::A("test".to_string()),
588                     MyEnum::B {
589                         name: "hello".to_string(),
590                         flag: true,
591                     },
592                     MyEnum::C,
593                 ],
594             }
595         );
596     }
597 
598     #[test]
deserialize_bytes()599     fn deserialize_bytes() {
600         #[derive(Debug, PartialEq)]
601         struct Item {
602             bytes: Vec<u8>,
603         }
604 
605         impl<'de> Deserialize<'de> for Item {
606             fn deserialize<D>(d: D) -> Result<Self, D::Error>
607             where
608                 D: serde::de::Deserializer<'de>,
609             {
610                 struct ItemVisitor;
611 
612                 impl<'de> de::Visitor<'de> for ItemVisitor {
613                     type Value = Item;
614 
615                     fn expecting(&self, fmt: &mut std::fmt::Formatter) -> std::fmt::Result {
616                         fmt.write_str("byte data")
617                     }
618 
619                     fn visit_byte_buf<E: de::Error>(self, v: Vec<u8>) -> Result<Self::Value, E> {
620                         Ok(Item { bytes: v })
621                     }
622                 }
623 
624                 Ok(d.deserialize_byte_buf(ItemVisitor)?)
625             }
626         }
627 
628         let s = r#"<item>bytes</item>"#;
629         let item: Item = from_reader(s.as_bytes()).unwrap();
630 
631         assert_eq!(
632             item,
633             Item {
634                 bytes: "bytes".as_bytes().to_vec(),
635             }
636         );
637     }
638 
639     /// Test for https://github.com/tafia/quick-xml/issues/231
640     #[test]
implicit_value()641     fn implicit_value() {
642         use serde_value::Value;
643 
644         let s = r#"<root>content</root>"#;
645         let item: Value = from_str(s).unwrap();
646 
647         assert_eq!(
648             item,
649             Value::Map(
650                 vec![(
651                     Value::String("$value".into()),
652                     Value::String("content".into())
653                 )]
654                 .into_iter()
655                 .collect()
656             )
657         );
658     }
659 
660     #[test]
explicit_value()661     fn explicit_value() {
662         #[derive(Debug, Deserialize, PartialEq)]
663         struct Item {
664             #[serde(rename = "$value")]
665             content: String,
666         }
667 
668         let s = r#"<root>content</root>"#;
669         let item: Item = from_str(s).unwrap();
670 
671         assert_eq!(
672             item,
673             Item {
674                 content: "content".into()
675             }
676         );
677     }
678 
679     #[test]
without_value()680     fn without_value() {
681         #[derive(Debug, Deserialize, PartialEq)]
682         struct Item;
683 
684         let s = r#"<root>content</root>"#;
685         let item: Item = from_str(s).unwrap();
686 
687         assert_eq!(item, Item);
688     }
689 
690     #[test]
unit()691     fn unit() {
692         #[derive(Debug, Deserialize, PartialEq)]
693         struct Unit;
694 
695         let data: Unit = from_str("<root/>").unwrap();
696         assert_eq!(data, Unit);
697     }
698 
699     #[test]
newtype()700     fn newtype() {
701         #[derive(Debug, Deserialize, PartialEq)]
702         struct Newtype(bool);
703 
704         let data: Newtype = from_str("<root>true</root>").unwrap();
705         assert_eq!(data, Newtype(true));
706     }
707 
708     #[test]
tuple()709     fn tuple() {
710         let data: (f32, String) = from_str("<root>42</root><root>answer</root>").unwrap();
711         assert_eq!(data, (42.0, "answer".into()));
712     }
713 
714     #[test]
tuple_struct()715     fn tuple_struct() {
716         #[derive(Debug, Deserialize, PartialEq)]
717         struct Tuple(f32, String);
718 
719         let data: Tuple = from_str("<root>42</root><root>answer</root>").unwrap();
720         assert_eq!(data, Tuple(42.0, "answer".into()));
721     }
722 
723     mod struct_ {
724         use super::*;
725 
726         #[derive(Debug, Deserialize, PartialEq)]
727         struct Struct {
728             float: f64,
729             string: String,
730         }
731 
732         #[test]
elements()733         fn elements() {
734             let data: Struct =
735                 from_str(r#"<root><float>42</float><string>answer</string></root>"#).unwrap();
736             assert_eq!(
737                 data,
738                 Struct {
739                     float: 42.0,
740                     string: "answer".into()
741                 }
742             );
743         }
744 
745         #[test]
attributes()746         fn attributes() {
747             let data: Struct = from_str(r#"<root float="42" string="answer"/>"#).unwrap();
748             assert_eq!(
749                 data,
750                 Struct {
751                     float: 42.0,
752                     string: "answer".into()
753                 }
754             );
755         }
756     }
757 
758     mod nested_struct {
759         use super::*;
760 
761         #[derive(Debug, Deserialize, PartialEq)]
762         struct Struct {
763             nested: Nested,
764             string: String,
765         }
766 
767         #[derive(Debug, Deserialize, PartialEq)]
768         struct Nested {
769             float: f32,
770         }
771 
772         #[test]
elements()773         fn elements() {
774             let data: Struct = from_str(
775                 r#"<root><string>answer</string><nested><float>42</float></nested></root>"#,
776             )
777             .unwrap();
778             assert_eq!(
779                 data,
780                 Struct {
781                     nested: Nested { float: 42.0 },
782                     string: "answer".into()
783                 }
784             );
785         }
786 
787         #[test]
attributes()788         fn attributes() {
789             let data: Struct =
790                 from_str(r#"<root string="answer"><nested float="42"/></root>"#).unwrap();
791             assert_eq!(
792                 data,
793                 Struct {
794                     nested: Nested { float: 42.0 },
795                     string: "answer".into()
796                 }
797             );
798         }
799     }
800 
801     mod flatten_struct {
802         use super::*;
803 
804         #[derive(Debug, Deserialize, PartialEq)]
805         struct Struct {
806             #[serde(flatten)]
807             nested: Nested,
808             string: String,
809         }
810 
811         #[derive(Debug, Deserialize, PartialEq)]
812         struct Nested {
813             //TODO: change to f64 after fixing https://github.com/serde-rs/serde/issues/1183
814             float: String,
815         }
816 
817         #[test]
818         #[ignore = "Prime cause: deserialize_any under the hood + https://github.com/serde-rs/serde/issues/1183"]
elements()819         fn elements() {
820             let data: Struct =
821                 from_str(r#"<root><float>42</float><string>answer</string></root>"#).unwrap();
822             assert_eq!(
823                 data,
824                 Struct {
825                     nested: Nested { float: "42".into() },
826                     string: "answer".into()
827                 }
828             );
829         }
830 
831         #[test]
attributes()832         fn attributes() {
833             let data: Struct = from_str(r#"<root float="42" string="answer"/>"#).unwrap();
834             assert_eq!(
835                 data,
836                 Struct {
837                     nested: Nested { float: "42".into() },
838                     string: "answer".into()
839                 }
840             );
841         }
842     }
843 
844     mod enum_ {
845         use super::*;
846 
847         mod externally_tagged {
848             use super::*;
849 
850             #[derive(Debug, Deserialize, PartialEq)]
851             enum Node {
852                 Unit,
853                 Newtype(bool),
854                 //TODO: serde bug https://github.com/serde-rs/serde/issues/1904
855                 // Tuple(f64, String),
856                 Struct {
857                     float: f64,
858                     string: String,
859                 },
860                 Holder {
861                     nested: Nested,
862                     string: String,
863                 },
864                 Flatten {
865                     #[serde(flatten)]
866                     nested: Nested,
867                     string: String,
868                 },
869             }
870 
871             #[derive(Debug, Deserialize, PartialEq)]
872             struct Nested {
873                 //TODO: change to f64 after fixing https://github.com/serde-rs/serde/issues/1183
874                 float: String,
875             }
876 
877             /// Workaround for serde bug https://github.com/serde-rs/serde/issues/1904
878             #[derive(Debug, Deserialize, PartialEq)]
879             enum Workaround {
880                 Tuple(f64, String),
881             }
882 
883             #[test]
unit()884             fn unit() {
885                 let data: Node = from_str("<Unit/>").unwrap();
886                 assert_eq!(data, Node::Unit);
887             }
888 
889             #[test]
newtype()890             fn newtype() {
891                 let data: Node = from_str("<Newtype>true</Newtype>").unwrap();
892                 assert_eq!(data, Node::Newtype(true));
893             }
894 
895             #[test]
tuple_struct()896             fn tuple_struct() {
897                 let data: Workaround = from_str("<Tuple>42</Tuple><Tuple>answer</Tuple>").unwrap();
898                 assert_eq!(data, Workaround::Tuple(42.0, "answer".into()));
899             }
900 
901             mod struct_ {
902                 use super::*;
903 
904                 #[test]
elements()905                 fn elements() {
906                     let data: Node =
907                         from_str(r#"<Struct><float>42</float><string>answer</string></Struct>"#)
908                             .unwrap();
909                     assert_eq!(
910                         data,
911                         Node::Struct {
912                             float: 42.0,
913                             string: "answer".into()
914                         }
915                     );
916                 }
917 
918                 #[test]
attributes()919                 fn attributes() {
920                     let data: Node = from_str(r#"<Struct float="42" string="answer"/>"#).unwrap();
921                     assert_eq!(
922                         data,
923                         Node::Struct {
924                             float: 42.0,
925                             string: "answer".into()
926                         }
927                     );
928                 }
929             }
930 
931             mod nested_struct {
932                 use super::*;
933 
934                 #[test]
elements()935                 fn elements() {
936                     let data: Node = from_str(
937                         r#"<Holder><string>answer</string><nested><float>42</float></nested></Holder>"#
938                     ).unwrap();
939                     assert_eq!(
940                         data,
941                         Node::Holder {
942                             nested: Nested { float: "42".into() },
943                             string: "answer".into()
944                         }
945                     );
946                 }
947 
948                 #[test]
attributes()949                 fn attributes() {
950                     let data: Node =
951                         from_str(r#"<Holder string="answer"><nested float="42"/></Holder>"#)
952                             .unwrap();
953                     assert_eq!(
954                         data,
955                         Node::Holder {
956                             nested: Nested { float: "42".into() },
957                             string: "answer".into()
958                         }
959                     );
960                 }
961             }
962 
963             mod flatten_struct {
964                 use super::*;
965 
966                 #[test]
967                 #[ignore = "Prime cause: deserialize_any under the hood + https://github.com/serde-rs/serde/issues/1183"]
elements()968                 fn elements() {
969                     let data: Node =
970                         from_str(r#"<Flatten><float>42</float><string>answer</string></Flatten>"#)
971                             .unwrap();
972                     assert_eq!(
973                         data,
974                         Node::Flatten {
975                             nested: Nested { float: "42".into() },
976                             string: "answer".into()
977                         }
978                     );
979                 }
980 
981                 #[test]
attributes()982                 fn attributes() {
983                     let data: Node = from_str(r#"<Flatten float="42" string="answer"/>"#).unwrap();
984                     assert_eq!(
985                         data,
986                         Node::Flatten {
987                             nested: Nested { float: "42".into() },
988                             string: "answer".into()
989                         }
990                     );
991                 }
992             }
993         }
994 
995         mod internally_tagged {
996             use super::*;
997 
998             #[derive(Debug, Deserialize, PartialEq)]
999             #[serde(tag = "tag")]
1000             enum Node {
1001                 Unit,
1002                 /// Primitives (such as `bool`) are not supported by serde in the internally tagged mode
1003                 Newtype(NewtypeContent),
1004                 // Tuple(f64, String),// Tuples are not supported in the internally tagged mode
1005                 //TODO: change to f64 after fixing https://github.com/serde-rs/serde/issues/1183
1006                 Struct {
1007                     float: String,
1008                     string: String,
1009                 },
1010                 Holder {
1011                     nested: Nested,
1012                     string: String,
1013                 },
1014                 Flatten {
1015                     #[serde(flatten)]
1016                     nested: Nested,
1017                     string: String,
1018                 },
1019             }
1020 
1021             #[derive(Debug, Deserialize, PartialEq)]
1022             struct NewtypeContent {
1023                 value: bool,
1024             }
1025 
1026             #[derive(Debug, Deserialize, PartialEq)]
1027             struct Nested {
1028                 //TODO: change to f64 after fixing https://github.com/serde-rs/serde/issues/1183
1029                 float: String,
1030             }
1031 
1032             mod unit {
1033                 use super::*;
1034 
1035                 #[test]
elements()1036                 fn elements() {
1037                     let data: Node = from_str(r#"<root><tag>Unit</tag></root>"#).unwrap();
1038                     assert_eq!(data, Node::Unit);
1039                 }
1040 
1041                 #[test]
attributes()1042                 fn attributes() {
1043                     let data: Node = from_str(r#"<root tag="Unit"/>"#).unwrap();
1044                     assert_eq!(data, Node::Unit);
1045                 }
1046             }
1047 
1048             mod newtype {
1049                 use super::*;
1050 
1051                 #[test]
1052                 #[ignore = "Prime cause: deserialize_any under the hood + https://github.com/serde-rs/serde/issues/1183"]
elements()1053                 fn elements() {
1054                     let data: Node =
1055                         from_str(r#"<root><tag>Newtype</tag><value>true</value></root>"#).unwrap();
1056                     assert_eq!(data, Node::Newtype(NewtypeContent { value: true }));
1057                 }
1058 
1059                 #[test]
1060                 #[ignore = "Prime cause: deserialize_any under the hood + https://github.com/serde-rs/serde/issues/1183"]
attributes()1061                 fn attributes() {
1062                     let data: Node = from_str(r#"<root tag="Newtype" value="true"/>"#).unwrap();
1063                     assert_eq!(data, Node::Newtype(NewtypeContent { value: true }));
1064                 }
1065             }
1066 
1067             mod struct_ {
1068                 use super::*;
1069 
1070                 #[test]
1071                 #[ignore = "Prime cause: deserialize_any under the hood + https://github.com/serde-rs/serde/issues/1183"]
elements()1072                 fn elements() {
1073                     let data: Node = from_str(
1074                         r#"<root><tag>Struct</tag><float>42</float><string>answer</string></root>"#,
1075                     )
1076                     .unwrap();
1077                     assert_eq!(
1078                         data,
1079                         Node::Struct {
1080                             float: "42".into(),
1081                             string: "answer".into()
1082                         }
1083                     );
1084                 }
1085 
1086                 #[test]
attributes()1087                 fn attributes() {
1088                     let data: Node =
1089                         from_str(r#"<root tag="Struct" float="42" string="answer"/>"#).unwrap();
1090                     assert_eq!(
1091                         data,
1092                         Node::Struct {
1093                             float: "42".into(),
1094                             string: "answer".into()
1095                         }
1096                     );
1097                 }
1098             }
1099 
1100             mod nested_struct {
1101                 use super::*;
1102 
1103                 #[test]
1104                 #[ignore = "Prime cause: deserialize_any under the hood + https://github.com/serde-rs/serde/issues/1183"]
elements()1105                 fn elements() {
1106                     let data: Node = from_str(
1107                         r#"<root><tag>Holder</tag><string>answer</string><nested><float>42</float></nested></root>"#
1108                     ).unwrap();
1109                     assert_eq!(
1110                         data,
1111                         Node::Holder {
1112                             nested: Nested { float: "42".into() },
1113                             string: "answer".into()
1114                         }
1115                     );
1116                 }
1117 
1118                 #[test]
attributes()1119                 fn attributes() {
1120                     let data: Node = from_str(
1121                         r#"<root tag="Holder" string="answer"><nested float="42"/></root>"#,
1122                     )
1123                     .unwrap();
1124                     assert_eq!(
1125                         data,
1126                         Node::Holder {
1127                             nested: Nested { float: "42".into() },
1128                             string: "answer".into()
1129                         }
1130                     );
1131                 }
1132             }
1133 
1134             mod flatten_struct {
1135                 use super::*;
1136 
1137                 #[test]
1138                 #[ignore = "Prime cause: deserialize_any under the hood + https://github.com/serde-rs/serde/issues/1183"]
elements()1139                 fn elements() {
1140                     let data: Node = from_str(
1141                         r#"<root><tag>Flatten</tag><float>42</float><string>answer</string></root>"#
1142                     ).unwrap();
1143                     assert_eq!(
1144                         data,
1145                         Node::Flatten {
1146                             nested: Nested { float: "42".into() },
1147                             string: "answer".into()
1148                         }
1149                     );
1150                 }
1151 
1152                 #[test]
attributes()1153                 fn attributes() {
1154                     let data: Node =
1155                         from_str(r#"<root tag="Flatten" float="42" string="answer"/>"#).unwrap();
1156                     assert_eq!(
1157                         data,
1158                         Node::Flatten {
1159                             nested: Nested { float: "42".into() },
1160                             string: "answer".into()
1161                         }
1162                     );
1163                 }
1164             }
1165         }
1166 
1167         mod adjacently_tagged {
1168             use super::*;
1169 
1170             #[derive(Debug, Deserialize, PartialEq)]
1171             #[serde(tag = "tag", content = "content")]
1172             enum Node {
1173                 Unit,
1174                 Newtype(bool),
1175                 //TODO: serde bug https://github.com/serde-rs/serde/issues/1904
1176                 // Tuple(f64, String),
1177                 Struct {
1178                     float: f64,
1179                     string: String,
1180                 },
1181                 Holder {
1182                     nested: Nested,
1183                     string: String,
1184                 },
1185                 Flatten {
1186                     #[serde(flatten)]
1187                     nested: Nested,
1188                     string: String,
1189                 },
1190             }
1191 
1192             #[derive(Debug, Deserialize, PartialEq)]
1193             struct Nested {
1194                 //TODO: change to f64 after fixing https://github.com/serde-rs/serde/issues/1183
1195                 float: String,
1196             }
1197 
1198             /// Workaround for serde bug https://github.com/serde-rs/serde/issues/1904
1199             #[derive(Debug, Deserialize, PartialEq)]
1200             #[serde(tag = "tag", content = "content")]
1201             enum Workaround {
1202                 Tuple(f64, String),
1203             }
1204 
1205             mod unit {
1206                 use super::*;
1207 
1208                 #[test]
elements()1209                 fn elements() {
1210                     let data: Node = from_str(r#"<root><tag>Unit</tag></root>"#).unwrap();
1211                     assert_eq!(data, Node::Unit);
1212                 }
1213 
1214                 #[test]
attributes()1215                 fn attributes() {
1216                     let data: Node = from_str(r#"<root tag="Unit"/>"#).unwrap();
1217                     assert_eq!(data, Node::Unit);
1218                 }
1219             }
1220 
1221             mod newtype {
1222                 use super::*;
1223 
1224                 #[test]
elements()1225                 fn elements() {
1226                     let data: Node =
1227                         from_str(r#"<root><tag>Newtype</tag><content>true</content></root>"#)
1228                             .unwrap();
1229                     assert_eq!(data, Node::Newtype(true));
1230                 }
1231 
1232                 #[test]
attributes()1233                 fn attributes() {
1234                     let data: Node = from_str(r#"<root tag="Newtype" content="true"/>"#).unwrap();
1235                     assert_eq!(data, Node::Newtype(true));
1236                 }
1237             }
1238 
1239             mod tuple_struct {
1240                 use super::*;
1241                 #[test]
elements()1242                 fn elements() {
1243                     let data: Workaround = from_str(
1244                         r#"<root><tag>Tuple</tag><content>42</content><content>answer</content></root>"#
1245                     ).unwrap();
1246                     assert_eq!(data, Workaround::Tuple(42.0, "answer".into()));
1247                 }
1248 
1249                 #[test]
1250                 #[ignore = "Prime cause: deserialize_any under the hood + https://github.com/serde-rs/serde/issues/1183"]
attributes()1251                 fn attributes() {
1252                     let data: Workaround = from_str(
1253                         r#"<root tag="Tuple" content="42"><content>answer</content></root>"#,
1254                     )
1255                     .unwrap();
1256                     assert_eq!(data, Workaround::Tuple(42.0, "answer".into()));
1257                 }
1258             }
1259 
1260             mod struct_ {
1261                 use super::*;
1262 
1263                 #[test]
elements()1264                 fn elements() {
1265                     let data: Node = from_str(
1266                         r#"<root><tag>Struct</tag><content><float>42</float><string>answer</string></content></root>"#
1267                     ).unwrap();
1268                     assert_eq!(
1269                         data,
1270                         Node::Struct {
1271                             float: 42.0,
1272                             string: "answer".into()
1273                         }
1274                     );
1275                 }
1276 
1277                 #[test]
attributes()1278                 fn attributes() {
1279                     let data: Node = from_str(
1280                         r#"<root tag="Struct"><content float="42" string="answer"/></root>"#,
1281                     )
1282                     .unwrap();
1283                     assert_eq!(
1284                         data,
1285                         Node::Struct {
1286                             float: 42.0,
1287                             string: "answer".into()
1288                         }
1289                     );
1290                 }
1291             }
1292 
1293             mod nested_struct {
1294                 use super::*;
1295 
1296                 #[test]
elements()1297                 fn elements() {
1298                     let data: Node = from_str(
1299                         r#"<root>
1300                             <tag>Holder</tag>
1301                             <content>
1302                                 <string>answer</string>
1303                                 <nested>
1304                                     <float>42</float>
1305                                 </nested>
1306                             </content>
1307                         </root>"#,
1308                     )
1309                     .unwrap();
1310                     assert_eq!(
1311                         data,
1312                         Node::Holder {
1313                             nested: Nested { float: "42".into() },
1314                             string: "answer".into()
1315                         }
1316                     );
1317                 }
1318 
1319                 #[test]
attributes()1320                 fn attributes() {
1321                     let data: Node = from_str(
1322                         r#"<root tag="Holder"><content string="answer"><nested float="42"/></content></root>"#
1323                     ).unwrap();
1324                     assert_eq!(
1325                         data,
1326                         Node::Holder {
1327                             nested: Nested { float: "42".into() },
1328                             string: "answer".into()
1329                         }
1330                     );
1331                 }
1332             }
1333 
1334             mod flatten_struct {
1335                 use super::*;
1336 
1337                 #[test]
1338                 #[ignore = "Prime cause: deserialize_any under the hood + https://github.com/serde-rs/serde/issues/1183"]
elements()1339                 fn elements() {
1340                     let data: Node = from_str(
1341                         r#"<root><tag>Flatten</tag><content><float>42</float><string>answer</string></content></root>"#
1342                     ).unwrap();
1343                     assert_eq!(
1344                         data,
1345                         Node::Flatten {
1346                             nested: Nested { float: "42".into() },
1347                             string: "answer".into()
1348                         }
1349                     );
1350                 }
1351 
1352                 #[test]
attributes()1353                 fn attributes() {
1354                     let data: Node = from_str(
1355                         r#"<root tag="Flatten"><content float="42" string="answer"/></root>"#,
1356                     )
1357                     .unwrap();
1358                     assert_eq!(
1359                         data,
1360                         Node::Flatten {
1361                             nested: Nested { float: "42".into() },
1362                             string: "answer".into()
1363                         }
1364                     );
1365                 }
1366             }
1367         }
1368 
1369         mod untagged {
1370             use super::*;
1371 
1372             #[derive(Debug, Deserialize, PartialEq)]
1373             #[serde(untagged)]
1374             enum Node {
1375                 Unit,
1376                 Newtype(bool),
1377                 // serde bug https://github.com/serde-rs/serde/issues/1904
1378                 // Tuple(f64, String),
1379                 Struct {
1380                     float: f64,
1381                     string: String,
1382                 },
1383                 Holder {
1384                     nested: Nested,
1385                     string: String,
1386                 },
1387                 Flatten {
1388                     #[serde(flatten)]
1389                     nested: Nested,
1390                     // Can't use "string" as name because in that case this variant
1391                     // will have no difference from `Struct` variant
1392                     string2: String,
1393                 },
1394             }
1395 
1396             #[derive(Debug, Deserialize, PartialEq)]
1397             struct Nested {
1398                 //TODO: change to f64 after fixing https://github.com/serde-rs/serde/issues/1183
1399                 float: String,
1400             }
1401 
1402             /// Workaround for serde bug https://github.com/serde-rs/serde/issues/1904
1403             #[derive(Debug, Deserialize, PartialEq)]
1404             #[serde(untagged)]
1405             enum Workaround {
1406                 Tuple(f64, String),
1407             }
1408 
1409             #[test]
1410             #[ignore = "Prime cause: deserialize_any under the hood + https://github.com/serde-rs/serde/issues/1183"]
unit()1411             fn unit() {
1412                 // Unit variant consists just from the tag, and because tags
1413                 // are not written, nothing is written
1414                 let data: Node = from_str("").unwrap();
1415                 assert_eq!(data, Node::Unit);
1416             }
1417 
1418             #[test]
1419             #[ignore = "Prime cause: deserialize_any under the hood + https://github.com/serde-rs/serde/issues/1183"]
newtype()1420             fn newtype() {
1421                 let data: Node = from_str("true").unwrap();
1422                 assert_eq!(data, Node::Newtype(true));
1423             }
1424 
1425             #[test]
1426             #[ignore = "Prime cause: deserialize_any under the hood + https://github.com/serde-rs/serde/issues/1183"]
tuple_struct()1427             fn tuple_struct() {
1428                 let data: Workaround = from_str("<root>42</root><root>answer</root>").unwrap();
1429                 assert_eq!(data, Workaround::Tuple(42.0, "answer".into()));
1430             }
1431 
1432             mod struct_ {
1433                 use super::*;
1434 
1435                 #[test]
1436                 #[ignore = "Prime cause: deserialize_any under the hood + https://github.com/serde-rs/serde/issues/1183"]
elements()1437                 fn elements() {
1438                     let data: Node =
1439                         from_str(r#"<root><float>42</float><string>answer</string></root>"#)
1440                             .unwrap();
1441                     assert_eq!(
1442                         data,
1443                         Node::Struct {
1444                             float: 42.0,
1445                             string: "answer".into()
1446                         }
1447                     );
1448                 }
1449 
1450                 #[test]
1451                 #[ignore = "Prime cause: deserialize_any under the hood + https://github.com/serde-rs/serde/issues/1183"]
attributes()1452                 fn attributes() {
1453                     let data: Node = from_str(r#"<root float="42" string="answer"/>"#).unwrap();
1454                     assert_eq!(
1455                         data,
1456                         Node::Struct {
1457                             float: 42.0,
1458                             string: "answer".into()
1459                         }
1460                     );
1461                 }
1462             }
1463 
1464             mod nested_struct {
1465                 use super::*;
1466 
1467                 #[test]
1468                 #[ignore = "Prime cause: deserialize_any under the hood + https://github.com/serde-rs/serde/issues/1183"]
elements()1469                 fn elements() {
1470                     let data: Node = from_str(
1471                         r#"<root><string>answer</string><nested><float>42</float></nested></root>"#,
1472                     )
1473                     .unwrap();
1474                     assert_eq!(
1475                         data,
1476                         Node::Holder {
1477                             nested: Nested { float: "42".into() },
1478                             string: "answer".into()
1479                         }
1480                     );
1481                 }
1482 
1483                 #[test]
attributes()1484                 fn attributes() {
1485                     let data: Node =
1486                         from_str(r#"<root string="answer"><nested float="42"/></root>"#).unwrap();
1487                     assert_eq!(
1488                         data,
1489                         Node::Holder {
1490                             nested: Nested { float: "42".into() },
1491                             string: "answer".into()
1492                         }
1493                     );
1494                 }
1495             }
1496 
1497             mod flatten_struct {
1498                 use super::*;
1499 
1500                 #[test]
1501                 #[ignore = "Prime cause: deserialize_any under the hood + https://github.com/serde-rs/serde/issues/1183"]
elements()1502                 fn elements() {
1503                     let data: Node =
1504                         from_str(r#"<root><float>42</float><string2>answer</string2></root>"#)
1505                             .unwrap();
1506                     assert_eq!(
1507                         data,
1508                         Node::Flatten {
1509                             nested: Nested { float: "42".into() },
1510                             string2: "answer".into()
1511                         }
1512                     );
1513                 }
1514 
1515                 #[test]
attributes()1516                 fn attributes() {
1517                     let data: Node = from_str(r#"<root float="42" string2="answer"/>"#).unwrap();
1518                     assert_eq!(
1519                         data,
1520                         Node::Flatten {
1521                             nested: Nested { float: "42".into() },
1522                             string2: "answer".into()
1523                         }
1524                     );
1525                 }
1526             }
1527         }
1528     }
1529 }
1530