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