diff options
author | hongmingjin <hongmingjin@google.com> | 2021-07-16 00:39:46 +0000 |
---|---|---|
committer | Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com> | 2021-07-16 00:39:46 +0000 |
commit | 4d090618367375aa7be3ba220fa47f0fc2e47c3a (patch) | |
tree | 4b825dc642cb6eb9a060e54bf8d69288fbee4904 | |
parent | ecb08a10cc17d51083df588c8324fad29973cd10 (diff) | |
parent | 1620dfabbf20dc28ead86e7cfcf97762b6962736 (diff) | |
download | serde-xml-rs-4d090618367375aa7be3ba220fa47f0fc2e47c3a.tar.gz |
Revert "Import serde-xml-rs 0.4.1" am: 1620dfabbf
Original change: https://android-review.googlesource.com/c/platform/external/rust/crates/serde-xml-rs/+/1769146
Change-Id: I8678b8aa3460dc8408406a01fc41a688f263b4b5
-rw-r--r-- | Android.bp | 34 | ||||
-rw-r--r-- | Cargo.toml | 18 | ||||
-rw-r--r-- | LICENSE | 21 | ||||
-rw-r--r-- | METADATA | 17 | ||||
-rw-r--r-- | MODULE_LICENSE_MIT | 0 | ||||
-rw-r--r-- | OWNERS | 2 | ||||
-rw-r--r-- | README.md | 62 | ||||
-rw-r--r-- | cargo2android.json | 9 | ||||
-rw-r--r-- | rustfmt.toml | 1 | ||||
-rw-r--r-- | src/de/map.rs | 126 | ||||
-rw-r--r-- | src/de/mod.rs | 367 | ||||
-rw-r--r-- | src/de/seq.rs | 70 | ||||
-rw-r--r-- | src/de/var.rs | 84 | ||||
-rw-r--r-- | src/error.rs | 104 | ||||
-rw-r--r-- | src/lib.rs | 55 | ||||
-rw-r--r-- | src/ser/mod.rs | 419 | ||||
-rw-r--r-- | src/ser/var.rs | 103 | ||||
-rw-r--r-- | tests/failures.rs | 52 | ||||
-rw-r--r-- | tests/migrated.rs | 1086 | ||||
-rw-r--r-- | tests/readme.rs | 6 | ||||
-rw-r--r-- | tests/round_trip.rs | 110 | ||||
-rw-r--r-- | tests/test.rs | 161 |
22 files changed, 0 insertions, 2907 deletions
diff --git a/Android.bp b/Android.bp deleted file mode 100644 index ee9f639..0000000 --- a/Android.bp +++ /dev/null @@ -1,34 +0,0 @@ -// This file is generated by cargo2android.py --config cargo2android.json. -// Do not modify this file as changes will be overridden on upgrade. - - - -rust_library { - name: "libserde_xml_rs", - host_supported: true, - crate_name: "serde_xml_rs", - srcs: ["src/lib.rs"], - edition: "2015", - rustlibs: [ - "liblog_rust", - "libserde", - "libthiserror", - "libxml", - ], - apex_available: [ - "//apex_available:platform", - "com.android.virt", - ], -} - -// dependent_library ["feature_list"] -// cfg-if-1.0.0 -// log-0.4.14 "std" -// proc-macro2-1.0.27 "default,proc-macro" -// quote-1.0.9 "default,proc-macro" -// serde-1.0.126 "default,std" -// syn-1.0.73 "clone-impls,default,derive,parsing,printing,proc-macro,quote" -// thiserror-1.0.26 -// thiserror-impl-1.0.26 -// unicode-xid-0.2.2 "default" -// xml-rs-0.8.3 diff --git a/Cargo.toml b/Cargo.toml deleted file mode 100644 index fa4d9b9..0000000 --- a/Cargo.toml +++ /dev/null @@ -1,18 +0,0 @@ -[package] -authors = ["Ingvar Stepanyan <me@rreverser.com>"] -description = "xml-rs based deserializer for Serde (compatible with 0.9+)" -license = "MIT" -name = "serde-xml-rs" -repository = "https://github.com/RReverser/serde-xml-rs" -version = "0.4.1" - -[dependencies] -log = "0.4" -serde = "1.0" -xml-rs = "0.8.0" -thiserror = "1.0" - -[dev-dependencies] -serde_derive = "1.0" -simple_logger = "1.0.1" -docmatic = "0.1.2" diff --git a/LICENSE b/LICENSE deleted file mode 100644 index 774d94a..0000000 --- a/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2017 Ingvar Stepanyan - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/METADATA b/METADATA deleted file mode 100644 index a1b4d08..0000000 --- a/METADATA +++ /dev/null @@ -1,17 +0,0 @@ -name: "serde-xml-rs" -description: - "xml-rs based deserializer for Serde" - -third_party { - url { - type: HOMEPAGE - value: "https://crates.io/crates/serde_xml_rs" - } - url { - type: GIT - value: "https://github.com/RReverser/serde-xml-rs" - } - version: "0.4.1" - last_upgrade_date { year: 2021 month: 6 day: 21 } - license_type: NOTICE -}
\ No newline at end of file diff --git a/MODULE_LICENSE_MIT b/MODULE_LICENSE_MIT deleted file mode 100644 index e69de29..0000000 --- a/MODULE_LICENSE_MIT +++ /dev/null @@ -1,2 +0,0 @@ -include platform/prebuilts/rust:/OWNERS - diff --git a/README.md b/README.md deleted file mode 100644 index f2e530c..0000000 --- a/README.md +++ /dev/null @@ -1,62 +0,0 @@ -# serde-xml-rs - -[![Build Status](https://travis-ci.org/RReverser/serde-xml-rs.svg?branch=master)](https://travis-ci.org/RReverser/serde-xml-rs) - -xml-rs based deserializer for Serde (compatible with 0.9+) - -## Usage - -Use `serde_xml_rs::from_reader(...)` on any type that implements [`std::io::Read`](https://doc.rust-lang.org/std/io/trait.Read.html) as following: - -```rust -#[macro_use] -extern crate serde_derive; -extern crate serde; -extern crate serde_xml_rs; - -use serde_xml_rs::from_reader; - -#[derive(Debug, Deserialize)] -struct Item { - pub name: String, - pub source: String -} - -#[derive(Debug, Deserialize)] -struct Project { - pub name: String, - - #[serde(rename = "Item", default)] - pub items: Vec<Item> -} - -fn main() { - let s = r##" - <Project name="my_project"> - <Item name="hello" source="world.rs" /> - </Project> - "##; - let project: Project = from_reader(s.as_bytes()).unwrap(); - println!("{:#?}", project); -} -``` - -Alternatively, you can use `serde_xml_rs::Deserializer` to create a deserializer from a preconfigured [`xml_rs::EventReader`](https://netvl.github.io/xml-rs/xml/reader/struct.EventReader.html). - -## Parsing the "value" of a tag - -If you have an input of the form `<foo abc="xyz">bar</foo>`, and you want to get at the`bar`, you can use the special name `$value`: - -```rust,ignore -struct Foo { - pub abc: String, - #[serde(rename = "$value")] - pub body: String, -} -``` - -## Parsed representations - -Deserializer tries to be as intuitive as possible. - -However, there are some edge cases where you might get unexpected errors, so it's best to check out [`tests`](tests/test.rs) for expectations. diff --git a/cargo2android.json b/cargo2android.json deleted file mode 100644 index 42b7833..0000000 --- a/cargo2android.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "apex-available": [ - "//apex_available:platform", - "com.android.virt" - ], - "dependencies": true, - "device": true, - "run": true -}
\ No newline at end of file diff --git a/rustfmt.toml b/rustfmt.toml deleted file mode 100644 index 8c795ae..0000000 --- a/rustfmt.toml +++ /dev/null @@ -1 +0,0 @@ -match_block_trailing_comma = true diff --git a/src/de/map.rs b/src/de/map.rs deleted file mode 100644 index ed1d0bb..0000000 --- a/src/de/map.rs +++ /dev/null @@ -1,126 +0,0 @@ -use std::io::Read; - -use serde::de::{self, IntoDeserializer, Unexpected}; -use xml::attribute::OwnedAttribute; -use xml::reader::XmlEvent; - -use Deserializer; -use error::{Error, Result}; - -pub struct MapAccess<'a, R: 'a + Read> { - attrs: ::std::vec::IntoIter<OwnedAttribute>, - next_value: Option<String>, - de: &'a mut Deserializer<R>, - inner_value: bool, -} - -impl<'a, R: 'a + Read> MapAccess<'a, R> { - pub fn new(de: &'a mut Deserializer<R>, attrs: Vec<OwnedAttribute>, inner_value: bool) -> Self { - MapAccess { - attrs: attrs.into_iter(), - next_value: None, - de: de, - inner_value: inner_value, - } - } -} - -impl<'de, 'a, R: 'a + Read> de::MapAccess<'de> for MapAccess<'a, R> { - type Error = Error; - - fn next_key_seed<K: de::DeserializeSeed<'de>>(&mut self, seed: K) -> Result<Option<K::Value>> { - debug_assert_eq!(self.next_value, None); - match self.attrs.next() { - Some(OwnedAttribute { name, value }) => { - self.next_value = Some(value); - seed.deserialize(name.local_name.into_deserializer()) - .map(Some) - }, - None => match *self.de.peek()? { - XmlEvent::StartElement { ref name, .. } => seed.deserialize( - if !self.inner_value { - name.local_name.as_str() - } else { - "$value" - }.into_deserializer(), - ).map(Some), - XmlEvent::Characters(_) => seed.deserialize("$value".into_deserializer()).map(Some), - _ => Ok(None), - }, - } - } - - fn next_value_seed<V: de::DeserializeSeed<'de>>(&mut self, seed: V) -> Result<V::Value> { - match self.next_value.take() { - Some(value) => seed.deserialize(AttrValueDeserializer(value)), - None => { - if !self.inner_value { - if let XmlEvent::StartElement { .. } = *self.de.peek()? { - self.de.set_map_value(); - } - } - let result = seed.deserialize(&mut *self.de)?; - Ok(result) - }, - } - } - - fn size_hint(&self) -> Option<usize> { - self.attrs.size_hint().1 - } -} - -struct AttrValueDeserializer(String); - -macro_rules! deserialize_type_attr { - ($deserialize:ident => $visit:ident) => { - fn $deserialize<V: de::Visitor<'de>>(self, visitor: V) -> Result<V::Value> { - visitor.$visit(self.0.parse()?) - } - } -} - -impl<'de> de::Deserializer<'de> for AttrValueDeserializer { - type Error = Error; - - fn deserialize_any<V: de::Visitor<'de>>(self, visitor: V) -> Result<V::Value> { - visitor.visit_string(self.0) - } - - deserialize_type_attr!(deserialize_i8 => visit_i8); - deserialize_type_attr!(deserialize_i16 => visit_i16); - deserialize_type_attr!(deserialize_i32 => visit_i32); - deserialize_type_attr!(deserialize_i64 => visit_i64); - deserialize_type_attr!(deserialize_u8 => visit_u8); - deserialize_type_attr!(deserialize_u16 => visit_u16); - deserialize_type_attr!(deserialize_u32 => visit_u32); - deserialize_type_attr!(deserialize_u64 => visit_u64); - deserialize_type_attr!(deserialize_f32 => visit_f32); - deserialize_type_attr!(deserialize_f64 => visit_f64); - - fn deserialize_enum<V: de::Visitor<'de>>( - self, - _name: &str, - _variants: &'static [&'static str], - visitor: V, - ) -> Result<V::Value> { - visitor.visit_enum(self.0.into_deserializer()) - } - - fn deserialize_option<V: de::Visitor<'de>>(self, visitor: V) -> Result<V::Value> { - visitor.visit_some(self) - } - - fn deserialize_bool<V: de::Visitor<'de>>(self, visitor: V) -> Result<V::Value> { - match self.0.as_str() { - "true" | "1" => visitor.visit_bool(true), - "false" | "0" => visitor.visit_bool(false), - _ => Err(de::Error::invalid_value(Unexpected::Str(&self.0), &"a boolean")), - } - } - - forward_to_deserialize_any! { - char str string unit seq bytes map unit_struct newtype_struct tuple_struct - struct identifier tuple ignored_any byte_buf - } -} diff --git a/src/de/mod.rs b/src/de/mod.rs deleted file mode 100644 index 94077c5..0000000 --- a/src/de/mod.rs +++ /dev/null @@ -1,367 +0,0 @@ -use std::io::Read; - -use serde::de::{self, Unexpected}; -use xml::name::OwnedName; -use xml::reader::{EventReader, ParserConfig, XmlEvent}; - -use self::map::MapAccess; -use self::seq::SeqAccess; -use self::var::EnumAccess; -use error::{Error, Result}; - -mod map; -mod seq; -mod var; - -/// A convenience method for deserialize some object from a string. -/// -/// ```rust -/// # #[macro_use] -/// # extern crate serde_derive; -/// # extern crate serde; -/// # extern crate serde_xml_rs; -/// # use serde_xml_rs::from_str; -/// #[derive(Debug, Deserialize, PartialEq)] -/// struct Item { -/// name: String, -/// source: String, -/// } -/// # fn main() { -/// let s = r##"<item name="hello" source="world.rs" />"##; -/// let item: Item = from_str(s).unwrap(); -/// assert_eq!(item, Item { name: "hello".to_string(),source: "world.rs".to_string()}); -/// # } -/// ``` -pub fn from_str<'de, T: de::Deserialize<'de>>(s: &str) -> Result<T> { - from_reader(s.as_bytes()) -} - -/// A convenience method for deserialize some object from a reader. -/// -/// ```rust -/// # #[macro_use] -/// # extern crate serde_derive; -/// # extern crate serde; -/// # extern crate serde_xml_rs; -/// # use serde_xml_rs::from_reader; -/// #[derive(Debug, Deserialize, PartialEq)] -/// struct Item { -/// name: String, -/// source: String, -/// } -/// # fn main() { -/// let s = r##"<item name="hello" source="world.rs" />"##; -/// let item: Item = from_reader(s.as_bytes()).unwrap(); -/// assert_eq!(item, Item { name: "hello".to_string(),source: "world.rs".to_string()}); -/// # } -/// ``` -pub fn from_reader<'de, R: Read, T: de::Deserialize<'de>>(reader: R) -> Result<T> { - T::deserialize(&mut Deserializer::new_from_reader(reader)) -} - -pub struct Deserializer<R: Read> { - depth: usize, - reader: EventReader<R>, - peeked: Option<XmlEvent>, - is_map_value: bool, -} - -impl<'de, R: Read> Deserializer<R> { - pub fn new(reader: EventReader<R>) -> Self { - Deserializer { - depth: 0, - reader: reader, - peeked: None, - is_map_value: false, - } - } - - pub fn new_from_reader(reader: R) -> Self { - let config = ParserConfig::new() - .trim_whitespace(true) - .whitespace_to_characters(true) - .cdata_to_characters(true) - .ignore_comments(true) - .coalesce_characters(true); - - Self::new(EventReader::new_with_config(reader, config)) - } - - fn peek(&mut self) -> Result<&XmlEvent> { - if self.peeked.is_none() { - self.peeked = Some(self.inner_next()?); - } - debug_expect!(self.peeked.as_ref(), Some(peeked) => { - debug!("Peeked {:?}", peeked); - Ok(peeked) - }) - } - - fn inner_next(&mut self) -> Result<XmlEvent> { - loop { - match self.reader.next()? { - XmlEvent::StartDocument { .. } - | XmlEvent::ProcessingInstruction { .. } - | XmlEvent::Whitespace { .. } - | XmlEvent::Comment(_) => { /* skip */ } - other => return Ok(other), - } - } - } - - fn next(&mut self) -> Result<XmlEvent> { - let next = if let Some(peeked) = self.peeked.take() { - peeked - } else { - self.inner_next()? - }; - match next { - XmlEvent::StartElement { .. } => { - self.depth += 1; - } - XmlEvent::EndElement { .. } => { - self.depth -= 1; - } - _ => {} - } - debug!("Fetched {:?}", next); - Ok(next) - } - - fn set_map_value(&mut self) { - self.is_map_value = true; - } - - pub fn unset_map_value(&mut self) -> bool { - ::std::mem::replace(&mut self.is_map_value, false) - } - - fn read_inner_value<V: de::Visitor<'de>, T, F: FnOnce(&mut Self) -> Result<T>>( - &mut self, - f: F, - ) -> Result<T> { - if self.unset_map_value() { - debug_expect!(self.next(), Ok(XmlEvent::StartElement { name, .. }) => { - let result = f(self)?; - self.expect_end_element(name)?; - Ok(result) - }) - } else { - f(self) - } - } - - fn expect_end_element(&mut self, start_name: OwnedName) -> Result<()> { - expect!(self.next()?, XmlEvent::EndElement { name, .. } => { - if name == start_name { - Ok(()) - } else { - Err(Error::Custom { field: format!( - "End tag </{}> didn't match the start tag <{}>", - name.local_name, - start_name.local_name - ) }) - } - }) - } - - fn prepare_parse_type<V: de::Visitor<'de>>(&mut self) -> Result<String> { - if let XmlEvent::StartElement { .. } = *self.peek()? { - self.set_map_value() - } - self.read_inner_value::<V, String, _>(|this| { - if let XmlEvent::EndElement { .. } = *this.peek()? { - return Err(Error::UnexpectedToken { - token: "EndElement".into(), - found: "Characters".into(), - }); - } - - expect!(this.next()?, XmlEvent::Characters(s) => { - return Ok(s) - }) - }) - } -} - -macro_rules! deserialize_type { - ($deserialize:ident => $visit:ident) => { - fn $deserialize<V: de::Visitor<'de>>(self, visitor: V) -> Result<V::Value> { - let value = self.prepare_parse_type::<V>()?.parse()?; - visitor.$visit(value) - } - } -} - -impl<'de, 'a, R: Read> de::Deserializer<'de> for &'a mut Deserializer<R> { - type Error = Error; - - forward_to_deserialize_any! { - identifier - } - - fn deserialize_struct<V: de::Visitor<'de>>( - self, - _name: &'static str, - fields: &'static [&'static str], - visitor: V, - ) -> Result<V::Value> { - self.unset_map_value(); - expect!(self.next()?, XmlEvent::StartElement { name, attributes, .. } => { - let map_value = visitor.visit_map(MapAccess::new( - self, - attributes, - fields.contains(&"$value") - ))?; - self.expect_end_element(name)?; - Ok(map_value) - }) - } - - deserialize_type!(deserialize_i8 => visit_i8); - deserialize_type!(deserialize_i16 => visit_i16); - deserialize_type!(deserialize_i32 => visit_i32); - deserialize_type!(deserialize_i64 => visit_i64); - deserialize_type!(deserialize_u8 => visit_u8); - deserialize_type!(deserialize_u16 => visit_u16); - deserialize_type!(deserialize_u32 => visit_u32); - deserialize_type!(deserialize_u64 => visit_u64); - deserialize_type!(deserialize_f32 => visit_f32); - deserialize_type!(deserialize_f64 => visit_f64); - - fn deserialize_bool<V: de::Visitor<'de>>(self, visitor: V) -> Result<V::Value> { - if let XmlEvent::StartElement { .. } = *self.peek()? { - self.set_map_value() - } - self.read_inner_value::<V, V::Value, _>(|this| { - if let XmlEvent::EndElement { .. } = *this.peek()? { - return visitor.visit_bool(false); - } - expect!(this.next()?, XmlEvent::Characters(s) => { - match s.as_str() { - "true" | "1" => visitor.visit_bool(true), - "false" | "0" => visitor.visit_bool(false), - _ => Err(de::Error::invalid_value(Unexpected::Str(&s), &"a boolean")), - } - - }) - }) - } - - fn deserialize_char<V: de::Visitor<'de>>(self, visitor: V) -> Result<V::Value> { - self.deserialize_string(visitor) - } - - fn deserialize_str<V: de::Visitor<'de>>(self, visitor: V) -> Result<V::Value> { - self.deserialize_string(visitor) - } - - fn deserialize_bytes<V: de::Visitor<'de>>(self, visitor: V) -> Result<V::Value> { - self.deserialize_string(visitor) - } - - fn deserialize_byte_buf<V: de::Visitor<'de>>(self, visitor: V) -> Result<V::Value> { - self.deserialize_string(visitor) - } - - fn deserialize_unit<V: de::Visitor<'de>>(self, visitor: V) -> Result<V::Value> { - if let XmlEvent::StartElement { .. } = *self.peek()? { - self.set_map_value() - } - self.read_inner_value::<V, V::Value, _>( - |this| expect!(this.peek()?, &XmlEvent::EndElement { .. } => visitor.visit_unit()), - ) - } - - fn deserialize_unit_struct<V: de::Visitor<'de>>( - self, - _name: &'static str, - visitor: V, - ) -> Result<V::Value> { - self.deserialize_unit(visitor) - } - - fn deserialize_newtype_struct<V: de::Visitor<'de>>( - self, - _name: &'static str, - visitor: V, - ) -> Result<V::Value> { - visitor.visit_newtype_struct(self) - } - - fn deserialize_tuple_struct<V: de::Visitor<'de>>( - self, - _name: &'static str, - len: usize, - visitor: V, - ) -> Result<V::Value> { - self.deserialize_tuple(len, visitor) - } - - fn deserialize_tuple<V: de::Visitor<'de>>(self, len: usize, visitor: V) -> Result<V::Value> { - visitor.visit_seq(SeqAccess::new(self, Some(len))) - } - - fn deserialize_enum<V: de::Visitor<'de>>( - self, - _name: &'static str, - _variants: &'static [&'static str], - visitor: V, - ) -> Result<V::Value> { - self.read_inner_value::<V, V::Value, _>(|this| visitor.visit_enum(EnumAccess::new(this))) - } - - fn deserialize_string<V: de::Visitor<'de>>(self, visitor: V) -> Result<V::Value> { - if let XmlEvent::StartElement { .. } = *self.peek()? { - self.set_map_value() - } - self.read_inner_value::<V, V::Value, _>(|this| { - if let XmlEvent::EndElement { .. } = *this.peek()? { - return visitor.visit_str(""); - } - expect!(this.next()?, XmlEvent::Characters(s) => { - visitor.visit_string(s) - }) - }) - } - - fn deserialize_seq<V: de::Visitor<'de>>(self, visitor: V) -> Result<V::Value> { - visitor.visit_seq(SeqAccess::new(self, None)) - } - - fn deserialize_map<V: de::Visitor<'de>>(self, visitor: V) -> Result<V::Value> { - self.unset_map_value(); - expect!(self.next()?, XmlEvent::StartElement { name, attributes, .. } => { - let map_value = visitor.visit_map(MapAccess::new(self, attributes, false))?; - self.expect_end_element(name)?; - Ok(map_value) - }) - } - - fn deserialize_option<V: de::Visitor<'de>>(self, visitor: V) -> Result<V::Value> { - match *self.peek()? { - XmlEvent::EndElement { .. } => visitor.visit_none(), - _ => visitor.visit_some(self), - } - } - - fn deserialize_ignored_any<V: de::Visitor<'de>>(self, visitor: V) -> Result<V::Value> { - self.unset_map_value(); - let depth = self.depth; - loop { - self.next()?; - if self.depth == depth { - break; - } - } - visitor.visit_unit() - } - - fn deserialize_any<V: de::Visitor<'de>>(self, visitor: V) -> Result<V::Value> { - match *self.peek()? { - XmlEvent::StartElement { .. } => self.deserialize_map(visitor), - XmlEvent::EndElement { .. } => self.deserialize_unit(visitor), - _ => self.deserialize_string(visitor), - } - } -} diff --git a/src/de/seq.rs b/src/de/seq.rs deleted file mode 100644 index 7e88d0c..0000000 --- a/src/de/seq.rs +++ /dev/null @@ -1,70 +0,0 @@ -use std::io::Read; - -use serde::de; -use xml::reader::XmlEvent; - -use de::Deserializer; -use error::{Error, Result}; - -pub struct SeqAccess<'a, R: 'a + Read> { - de: &'a mut Deserializer<R>, - max_size: Option<usize>, - expected_name: Option<String>, -} - -impl<'a, R: 'a + Read> SeqAccess<'a, R> { - pub fn new(de: &'a mut Deserializer<R>, max_size: Option<usize>) -> Self { - let expected_name = if de.unset_map_value() { - debug_expect!(de.peek(), Ok(&XmlEvent::StartElement { ref name, .. }) => { - Some(name.local_name.clone()) - }) - } else { - None - }; - SeqAccess { - de: de, - max_size: max_size, - expected_name: expected_name, - } - } -} - -impl<'de, 'a, R: 'a + Read> de::SeqAccess<'de> for SeqAccess<'a, R> { - type Error = Error; - - fn next_element_seed<T: de::DeserializeSeed<'de>>( - &mut self, - seed: T, - ) -> Result<Option<T::Value>> { - match self.max_size.as_mut() { - Some(&mut 0) => { - return Ok(None); - }, - Some(max_size) => { - *max_size -= 1; - }, - None => {}, - } - let more = match (self.de.peek()?, self.expected_name.as_ref()) { - (&XmlEvent::StartElement { ref name, .. }, Some(expected_name)) => { - &name.local_name == expected_name - }, - (&XmlEvent::EndElement { .. }, None) | - (_, Some(_)) | - (&XmlEvent::EndDocument { .. }, _) => false, - (_, None) => true, - }; - if more { - if self.expected_name.is_some() { - self.de.set_map_value(); - } - seed.deserialize(&mut *self.de).map(Some) - } else { - Ok(None) - } - } - - fn size_hint(&self) -> Option<usize> { - self.max_size - } -} diff --git a/src/de/var.rs b/src/de/var.rs deleted file mode 100644 index dbb400f..0000000 --- a/src/de/var.rs +++ /dev/null @@ -1,84 +0,0 @@ -use std::io::Read; - -use serde::de::{self, Deserializer as SerdeDeserializer, IntoDeserializer}; -use xml::name::OwnedName; -use xml::reader::XmlEvent; - -use de::Deserializer; -use error::{Error, Result}; - -pub struct EnumAccess<'a, R: 'a + Read> { - de: &'a mut Deserializer<R>, -} - -impl<'a, R: 'a + Read> EnumAccess<'a, R> { - pub fn new(de: &'a mut Deserializer<R>) -> Self { - EnumAccess { de: de } - } -} - -impl<'de, 'a, R: 'a + Read> de::EnumAccess<'de> for EnumAccess<'a, R> { - type Error = Error; - type Variant = VariantAccess<'a, R>; - - fn variant_seed<V: de::DeserializeSeed<'de>>( - self, - seed: V, - ) -> Result<(V::Value, VariantAccess<'a, R>)> { - let name = expect!( - self.de.peek()?, - - &XmlEvent::Characters(ref name) | - &XmlEvent::StartElement { name: OwnedName { local_name: ref name, .. }, .. } => { - seed.deserialize(name.as_str().into_deserializer()) - } - )?; - self.de.set_map_value(); - Ok((name, VariantAccess::new(self.de))) - } -} - -pub struct VariantAccess<'a, R: 'a + Read> { - de: &'a mut Deserializer<R>, -} - -impl<'a, R: 'a + Read> VariantAccess<'a, R> { - pub fn new(de: &'a mut Deserializer<R>) -> Self { - VariantAccess { de: de } - } -} - -impl<'de, 'a, R: 'a + Read> de::VariantAccess<'de> for VariantAccess<'a, R> { - type Error = Error; - - fn unit_variant(self) -> Result<()> { - self.de.unset_map_value(); - match self.de.next()? { - XmlEvent::StartElement { - name, attributes, .. - } => if attributes.is_empty() { - self.de.expect_end_element(name) - } else { - Err(de::Error::invalid_length(attributes.len(), &"0")) - }, - XmlEvent::Characters(_) => Ok(()), - _ => unreachable!(), - } - } - - fn newtype_variant_seed<T: de::DeserializeSeed<'de>>(self, seed: T) -> Result<T::Value> { - seed.deserialize(&mut *self.de) - } - - fn tuple_variant<V: de::Visitor<'de>>(self, len: usize, visitor: V) -> Result<V::Value> { - self.de.deserialize_tuple(len, visitor) - } - - fn struct_variant<V: de::Visitor<'de>>( - self, - _fields: &'static [&'static str], - visitor: V, - ) -> Result<V::Value> { - self.de.deserialize_map(visitor) - } -} diff --git a/src/error.rs b/src/error.rs deleted file mode 100644 index 8d6e4ad..0000000 --- a/src/error.rs +++ /dev/null @@ -1,104 +0,0 @@ -use serde::de::Error as DeError; -use serde::ser::Error as SerError; -use std::fmt::Display; -use thiserror::Error; - -#[derive(Debug, Error)] -pub enum Error { - #[error("Expected token {token}, found {found}")] - UnexpectedToken { token: String, found: String }, - #[error("custom: {field}")] - Custom { field: String }, - #[error("unsupported operation: '{operation}'")] - UnsupportedOperation { operation: String }, - - #[error("IO error: {source}")] - Io { - #[from] - source: ::std::io::Error, - }, - - #[error("FromUtf8Error: {source}")] - FromUtf8Error { - #[from] - source: ::std::string::FromUtf8Error, - }, - - #[error("ParseIntError: {source}")] - ParseIntError { - #[from] - source: ::std::num::ParseIntError, - }, - - #[error("ParseFloatError: {source}")] - ParseFloatError { - #[from] - source: ::std::num::ParseFloatError, - }, - - #[error("ParseBoolError: {source}")] - ParseBoolError { - #[from] - source: ::std::str::ParseBoolError, - }, - - #[error("Syntax: {source}")] - Syntax { - #[from] - source: ::xml::reader::Error, - }, -} - -pub type Result<T> = std::result::Result<T, Error>; - -macro_rules! expect { - ($actual: expr, $($expected: pat)|+ => $if_ok: expr) => { - match $actual { - $($expected)|+ => $if_ok, - actual => Err($crate::Error::UnexpectedToken { - token: stringify!($($expected)|+).to_string(), - found: format!("{:?}",actual) - }) as Result<_> - } - } -} - -#[cfg(debug_assertions)] -macro_rules! debug_expect { - ($actual: expr, $($expected: pat)|+ => $if_ok: expr) => { - match $actual { - $($expected)|+ => $if_ok, - actual => panic!( - "Internal error: Expected token {}, found {:?}", - stringify!($($expected)|+), - actual - ) - } - } -} - -#[cfg(not(debug_assertions))] -macro_rules! debug_expect { - ($actual: expr, $($expected: pat)|+ => $if_ok: expr) => { - match $actual { - $($expected)|+ => $if_ok, - _ => unreachable!() - } - } -} - -impl DeError for Error { - fn custom<T: Display>(msg: T) -> Self { - Error::Custom { - field: msg.to_string(), - } - } -} - -impl SerError for Error { - fn custom<T: Display>(msg: T) -> Self { - Error::Custom { - field: msg.to_string(), - } - } -} diff --git a/src/lib.rs b/src/lib.rs deleted file mode 100644 index 1f93ed8..0000000 --- a/src/lib.rs +++ /dev/null @@ -1,55 +0,0 @@ -//! -//! -//! # Examples -//! -//! ```rust -//! extern crate serde; -//! extern crate serde_xml_rs; -//! -//! #[macro_use] -//! extern crate serde_derive; -//! -//! use serde_xml_rs::{from_str, to_string}; -//! -//! #[derive(Debug, Serialize, Deserialize, PartialEq)] -//! struct Item { -//! name: String, -//! source: String, -//! } -//! -//! fn main() { -//! let src = r#"<Item><name>Banana</name><source>Store</source></Item>"#; -//! let should_be = Item { -//! name: "Banana".to_string(), -//! source: "Store".to_string(), -//! }; -//! -//! let item: Item = from_str(src).unwrap(); -//! assert_eq!(item, should_be); -//! -//! let reserialized_item = to_string(&item).unwrap(); -//! assert_eq!(src, reserialized_item); -//! } -//! ``` - -#[macro_use] -extern crate log; -#[macro_use] -extern crate serde; -extern crate xml; - -extern crate thiserror; - -#[cfg(test)] -#[macro_use] -extern crate serde_derive; - -#[macro_use] -mod error; -pub mod de; -pub mod ser; - -pub use de::{from_reader, from_str, Deserializer}; -pub use error::Error; -pub use ser::{to_string, to_writer, Serializer}; -pub use xml::reader::{EventReader, ParserConfig}; diff --git a/src/ser/mod.rs b/src/ser/mod.rs deleted file mode 100644 index bf97b1f..0000000 --- a/src/ser/mod.rs +++ /dev/null @@ -1,419 +0,0 @@ -use std::fmt::Display; -use std::io::Write; - -use serde::ser::{self, Impossible, Serialize}; - -use self::var::{Map, Struct}; -use error::{Error, Result}; - -mod var; - -/// A convenience method for serializing some object to a buffer. -/// -/// # Examples -/// -/// ```rust -/// # #[macro_use] -/// # extern crate serde_derive; -/// # extern crate serde; -/// # extern crate serde_xml_rs; -/// # use serde_xml_rs::to_writer; -/// #[derive(Serialize)] -/// struct Person { -/// name: String, -/// age: u32, -/// } -/// -/// # fn main() { -/// let mut buffer = Vec::new(); -/// let joe = Person {name: "Joe".to_string(), age: 42}; -/// -/// to_writer(&mut buffer, &joe).unwrap(); -/// -/// let serialized = String::from_utf8(buffer).unwrap(); -/// println!("{}", serialized); -/// # } -/// ``` -pub fn to_writer<W: Write, S: Serialize>(writer: W, value: &S) -> Result<()> { - let mut ser = Serializer::new(writer); - value.serialize(&mut ser) -} - -/// A convenience method for serializing some object to a string. -/// -/// # Examples -/// -/// ```rust -/// # #[macro_use] -/// # extern crate serde_derive; -/// # extern crate serde; -/// # extern crate serde_xml_rs; -/// # use serde_xml_rs::to_string; -/// #[derive(Serialize)] -/// struct Person { -/// name: String, -/// age: u32, -/// } -/// -/// # fn main() { -/// -/// let joe = Person {name: "Joe".to_string(), age: 42}; -/// let serialized = to_string(&joe).unwrap(); -/// println!("{}", serialized); -/// # } -/// ``` -pub fn to_string<S: Serialize>(value: &S) -> Result<String> { - // Create a buffer and serialize our nodes into it - let mut writer = Vec::with_capacity(128); - to_writer(&mut writer, value)?; - - // We then check that the serialized string is the same as what we expect - let string = String::from_utf8(writer)?; - Ok(string) -} - -/// An XML `Serializer`. -pub struct Serializer<W> -where - W: Write, -{ - writer: W, -} - -impl<W> Serializer<W> -where - W: Write, -{ - pub fn new(writer: W) -> Self { - Self { writer: writer } - } - - fn write_primitive<P: Display>(&mut self, primitive: P) -> Result<()> { - write!(self.writer, "{}", primitive)?; - Ok(()) - } - - fn write_wrapped<S: Serialize>(&mut self, tag: &str, value: S) -> Result<()> { - write!(self.writer, "<{}>", tag)?; - value.serialize(&mut *self)?; - write!(self.writer, "</{}>", tag)?; - Ok(()) - } -} - -#[allow(unused_variables)] -impl<'w, W> ser::Serializer for &'w mut Serializer<W> -where - W: Write, -{ - type Ok = (); - type Error = Error; - - type SerializeSeq = Impossible<Self::Ok, Self::Error>; - type SerializeTuple = Impossible<Self::Ok, Self::Error>; - type SerializeTupleStruct = Impossible<Self::Ok, Self::Error>; - type SerializeTupleVariant = Impossible<Self::Ok, Self::Error>; - type SerializeMap = Map<'w, W>; - type SerializeStruct = Struct<'w, W>; - type SerializeStructVariant = Impossible<Self::Ok, Self::Error>; - - fn serialize_bool(self, v: bool) -> Result<Self::Ok> { - if v { - write!(self.writer, "true")?; - } else { - write!(self.writer, "false")?; - } - - Ok(()) - } - - fn serialize_i8(self, v: i8) -> Result<Self::Ok> { - self.write_primitive(v) - } - - fn serialize_i16(self, v: i16) -> Result<Self::Ok> { - self.write_primitive(v) - } - - fn serialize_i32(self, v: i32) -> Result<Self::Ok> { - self.write_primitive(v) - } - - fn serialize_i64(self, v: i64) -> Result<Self::Ok> { - self.write_primitive(v) - } - - fn serialize_u8(self, v: u8) -> Result<Self::Ok> { - self.write_primitive(v) - } - - fn serialize_u16(self, v: u16) -> Result<Self::Ok> { - self.write_primitive(v) - } - - fn serialize_u32(self, v: u32) -> Result<Self::Ok> { - self.write_primitive(v) - } - - fn serialize_u64(self, v: u64) -> Result<Self::Ok> { - self.write_primitive(v) - } - - fn serialize_f32(self, v: f32) -> Result<Self::Ok> { - self.write_primitive(v) - } - - fn serialize_f64(self, v: f64) -> Result<Self::Ok> { - self.write_primitive(v) - } - - fn serialize_char(self, v: char) -> Result<Self::Ok> { - self.write_primitive(v) - } - - fn serialize_str(self, value: &str) -> Result<Self::Ok> { - self.write_primitive(value) - } - - fn serialize_bytes(self, value: &[u8]) -> Result<Self::Ok> { - // TODO: I imagine you'd want to use base64 here. - // Not sure how to roundtrip effectively though... - Err(Error::UnsupportedOperation { - operation: "serialize_bytes".to_string(), - }) - } - - fn serialize_none(self) -> Result<Self::Ok> { - Ok(()) - } - - fn serialize_some<T: ?Sized + Serialize>(self, value: &T) -> Result<Self::Ok> { - value.serialize(self) - } - - fn serialize_unit(self) -> Result<Self::Ok> { - self.serialize_none() - } - - fn serialize_unit_struct(self, name: &'static str) -> Result<Self::Ok> { - self.write_wrapped(name, ()) - } - - fn serialize_unit_variant( - self, - name: &'static str, - variant_index: u32, - variant: &'static str, - ) -> Result<Self::Ok> { - Err(Error::UnsupportedOperation { - operation: "serialize_unit_variant".to_string(), - }) - } - - fn serialize_newtype_struct<T: ?Sized + Serialize>( - self, - name: &'static str, - value: &T, - ) -> Result<Self::Ok> { - Err(Error::UnsupportedOperation { - operation: "serialize_newtype_struct".to_string(), - }) - } - - fn serialize_newtype_variant<T: ?Sized + Serialize>( - self, - name: &'static str, - variant_index: u32, - variant: &'static str, - value: &T, - ) -> Result<Self::Ok> { - self.write_wrapped(variant, value) - } - - fn serialize_seq(self, len: Option<usize>) -> Result<Self::SerializeSeq> { - // TODO: Figure out how to constrain the things written to only be composites - Err(Error::UnsupportedOperation { - operation: "serialize_seq".to_string(), - }) - } - - fn serialize_tuple(self, len: usize) -> Result<Self::SerializeTuple> { - Err(Error::UnsupportedOperation { - operation: "serialize_tuple".to_string(), - }) - } - - fn serialize_tuple_struct( - self, - name: &'static str, - len: usize, - ) -> Result<Self::SerializeTupleStruct> { - Err(Error::UnsupportedOperation { - operation: "serialize_tuple_struct".to_string(), - }) - } - - fn serialize_tuple_variant( - self, - name: &'static str, - variant_index: u32, - variant: &'static str, - len: usize, - ) -> Result<Self::SerializeTupleVariant> { - Err(Error::UnsupportedOperation { - operation: "serialize_tuple_variant".to_string(), - }) - } - - fn serialize_map(self, len: Option<usize>) -> Result<Self::SerializeMap> { - Ok(Map::new(self)) - } - - fn serialize_struct(self, name: &'static str, len: usize) -> Result<Self::SerializeStruct> { - write!(self.writer, "<{}>", name)?; - Ok(Struct::new(self, name)) - } - - fn serialize_struct_variant( - self, - name: &'static str, - variant_index: u32, - variant: &'static str, - len: usize, - ) -> Result<Self::SerializeStructVariant> { - Err(Error::UnsupportedOperation { - operation: "Result".to_string(), - }) - } -} - -#[cfg(test)] -mod tests { - use super::*; - use serde::ser::{SerializeMap, SerializeStruct}; - use serde::Serializer as SerSerializer; - - #[test] - fn test_serialize_bool() { - let inputs = vec![(true, "true"), (false, "false")]; - - for (src, should_be) in inputs { - let mut buffer = Vec::new(); - - { - let mut ser = Serializer::new(&mut buffer); - ser.serialize_bool(src).unwrap(); - } - - let got = String::from_utf8(buffer).unwrap(); - assert_eq!(got, should_be); - } - } - - #[test] - fn test_start_serialize_struct() { - let mut buffer = Vec::new(); - - { - let mut ser = Serializer::new(&mut buffer); - let _ = ser.serialize_struct("foo", 0).unwrap(); - } - - let got = String::from_utf8(buffer).unwrap(); - assert_eq!(got, "<foo>"); - } - - #[test] - fn test_serialize_struct_field() { - let mut buffer = Vec::new(); - - { - let mut ser = Serializer::new(&mut buffer); - let mut struct_ser = Struct::new(&mut ser, "baz"); - struct_ser.serialize_field("foo", "bar").unwrap(); - } - - let got = String::from_utf8(buffer).unwrap(); - assert_eq!(got, "<foo>bar</foo>"); - } - - #[test] - fn test_serialize_struct() { - #[derive(Serialize)] - struct Person { - name: String, - age: u32, - } - - let bob = Person { - name: "Bob".to_string(), - age: 42, - }; - let should_be = "<Person><name>Bob</name><age>42</age></Person>"; - let mut buffer = Vec::new(); - - { - let mut ser = Serializer::new(&mut buffer); - bob.serialize(&mut ser).unwrap(); - } - - let got = String::from_utf8(buffer).unwrap(); - assert_eq!(got, should_be); - } - - #[test] - fn test_serialize_map_entries() { - let should_be = "<name>Bob</name><age>5</age>"; - let mut buffer = Vec::new(); - - { - let mut ser = Serializer::new(&mut buffer); - let mut map = Map::new(&mut ser); - map.serialize_entry("name", "Bob").unwrap(); - map.serialize_entry("age", "5").unwrap(); - } - - let got = String::from_utf8(buffer).unwrap(); - assert_eq!(got, should_be); - } - - #[test] - fn test_serialize_enum() { - #[derive(Serialize)] - #[allow(dead_code)] - enum Node { - Boolean(bool), - Number(f64), - String(String), - } - - let mut buffer = Vec::new(); - let should_be = "<Boolean>true</Boolean>"; - - { - let mut ser = Serializer::new(&mut buffer); - let node = Node::Boolean(true); - node.serialize(&mut ser).unwrap(); - } - - let got = String::from_utf8(buffer).unwrap(); - assert_eq!(got, should_be); - } - - #[test] - #[ignore] - fn serialize_a_list() { - let inputs = vec![1, 2, 3, 4]; - - let mut buffer = Vec::new(); - - { - let mut ser = Serializer::new(&mut buffer); - inputs.serialize(&mut ser).unwrap(); - } - - let got = String::from_utf8(buffer).unwrap(); - println!("{}", got); - panic!(); - } -} diff --git a/src/ser/var.rs b/src/ser/var.rs deleted file mode 100644 index bb61472..0000000 --- a/src/ser/var.rs +++ /dev/null @@ -1,103 +0,0 @@ -use std::io::Write; - -use serde::ser::{self, Serialize}; - -use ser::Serializer; -use error::{Error, Result}; - -/// An implementation of `SerializeMap` for serializing to XML. -pub struct Map<'w, W> -where - W: 'w + Write, -{ - parent: &'w mut Serializer<W>, -} - -impl<'w, W> Map<'w, W> -where - W: 'w + Write, -{ - pub fn new(parent: &'w mut Serializer<W>) -> Map<'w, W> { - Map { parent } - } -} - -impl<'w, W> ser::SerializeMap for Map<'w, W> -where - W: 'w + Write, -{ - type Ok = (); - type Error = Error; - - fn serialize_key<T: ?Sized + Serialize>(&mut self, _: &T) -> Result<()> { - panic!("impossible to serialize the key on its own, please use serialize_entry()") - } - - fn serialize_value<T: ?Sized + Serialize>(&mut self, value: &T) -> Result<()> { - value.serialize(&mut *self.parent) - } - - fn end(self) -> Result<Self::Ok> { - Ok(()) - } - - fn serialize_entry<K: ?Sized + Serialize, V: ?Sized + Serialize>( - &mut self, - key: &K, - value: &V, - ) -> Result<()> { - // TODO: Is it possible to ensure our key is never a composite type? - // Anything which isn't a "primitive" would lead to malformed XML here... - write!(self.parent.writer, "<")?; - key.serialize(&mut *self.parent)?; - write!(self.parent.writer, ">")?; - - value.serialize(&mut *self.parent)?; - - write!(self.parent.writer, "</")?; - key.serialize(&mut *self.parent)?; - write!(self.parent.writer, ">")?; - Ok(()) - } -} - -/// An implementation of `SerializeStruct` for serializing to XML. -pub struct Struct<'w, W> -where - W: 'w + Write, -{ - parent: &'w mut Serializer<W>, - name: &'w str, -} - -impl<'w, W> Struct<'w, W> -where - W: 'w + Write, -{ - pub fn new(parent: &'w mut Serializer<W>, name: &'w str) -> Struct<'w, W> { - Struct { parent, name } - } -} - -impl<'w, W> ser::SerializeStruct for Struct<'w, W> -where - W: 'w + Write, -{ - type Ok = (); - type Error = Error; - - fn serialize_field<T: ?Sized + Serialize>( - &mut self, - key: &'static str, - value: &T, - ) -> Result<()> { - write!(self.parent.writer, "<{}>", key)?; - value.serialize(&mut *self.parent)?; - write!(self.parent.writer, "</{}>", key)?; - Ok(()) - } - - fn end(self) -> Result<Self::Ok> { - write!(self.parent.writer, "</{}>", self.name).map_err(|e| e.into()) - } -} diff --git a/tests/failures.rs b/tests/failures.rs deleted file mode 100644 index ca51f6b..0000000 --- a/tests/failures.rs +++ /dev/null @@ -1,52 +0,0 @@ -#[macro_use] -extern crate serde_derive; -extern crate serde_xml_rs; - -#[macro_use] -extern crate log; -extern crate simple_logger; - -use serde_xml_rs::from_str; - -#[derive(Debug, Deserialize, PartialEq)] -struct Item { - name: String, - source: String, -} - -#[test] -fn simple_struct_from_attributes_should_fail() { - let _ = simple_logger::init(); - - let s = r##" - <item name="hello" source="world.rs /> - "##; - - let item: Result<Item, _> = from_str(s); - match item { - Ok(_) => assert!(false), - Err(e) => { - info!("simple_struct_from_attributes_should_fail(): {}", e); - assert!(true) - } - } -} - -#[test] -fn multiple_roots_attributes_should_fail() { - let _ = simple_logger::init(); - - let s = r##" - <item name="hello" source="world.rs" /> - <item name="hello source="world.rs" /> - "##; - - let item: Result<Vec<Item>, _> = from_str(s); - match item { - Ok(_) => assert!(false), - Err(e) => { - info!("multiple_roots_attributes_should_fail(): {}", e); - assert!(true) - } - } -} diff --git a/tests/migrated.rs b/tests/migrated.rs deleted file mode 100644 index 87d3e6a..0000000 --- a/tests/migrated.rs +++ /dev/null @@ -1,1086 +0,0 @@ -#[macro_use] -extern crate serde_derive; - -extern crate log; -extern crate simple_logger; - -extern crate serde; -extern crate serde_xml_rs; - -use std::fmt::Debug; - -use serde::{de, ser}; -use serde_xml_rs::{from_str, Error}; - -#[derive(PartialEq, Debug, Serialize, Deserialize)] -enum Animal { - Dog, - Frog(String), - Ant(Simple), - Cat { age: usize, name: String }, -} - -#[derive(PartialEq, Debug, Serialize, Deserialize)] -struct Simple { - a: (), - b: usize, - c: String, - d: Option<String>, -} - -#[derive(PartialEq, Debug, Serialize, Deserialize)] -struct Inner { - a: (), - b: (usize, String, i8), - c: Vec<String>, -} - -#[derive(PartialEq, Debug, Serialize, Deserialize)] -struct Outer { - inner: Option<Inner>, -} - -fn test_parse_ok<'de, 'a, T>(errors: &[(&'a str, T)]) -where - T: PartialEq + Debug + ser::Serialize + de::Deserialize<'de>, -{ - for &(s, ref value) in errors { - let v: T = from_str(s).unwrap(); - assert_eq!(v, *value); - - // // Make sure we can deserialize into an `Element`. - // let xml_value: Element = from_str(s).unwrap(); - - // // Make sure we can deserialize from an `Element`. - // let v: T = from_value(xml_value.clone()).unwrap(); - // assert_eq!(v, *value); - } -} - -fn test_parse_err<'de, 'a, T>(errors: &[&'a str]) -where - T: PartialEq + Debug + ser::Serialize + de::Deserialize<'de>, -{ - for &s in errors { - assert!(match from_str::<T>(s) { - Err(Error::Syntax { source: _ }) => true, - _ => false, - }); - } -} - -fn test_parse_invalid<'de, 'a, T>(errors: &[&'a str]) -where - T: PartialEq + Debug + ser::Serialize + de::Deserialize<'de>, -{ - for &s in errors { - assert!(match from_str::<T>(s) { - Err(_) => true, - _ => false, - }); - } -} - -#[test] -fn test_namespaces() { - let _ = simple_logger::init(); - #[derive(PartialEq, Serialize, Deserialize, Debug)] - struct Envelope { - subject: String, - } - let s = r#" - <?xml version="1.0" encoding="UTF-8"?> - <gesmes:Envelope xmlns:gesmes="http://www.gesmes.org/xml/2002-08-01" xmlns="http://www.ecb.int/vocabulary/2002-08-01/eurofxref"> - <gesmes:subject>Reference rates</gesmes:subject> - </gesmes:Envelope>"#; - test_parse_ok(&[( - s, - Envelope { - subject: "Reference rates".to_string(), - }, - )]); -} - -#[test] -#[ignore] // FIXME -fn test_doctype() { - let _ = simple_logger::init(); - #[derive(PartialEq, Serialize, Deserialize, Debug)] - struct Envelope { - subject: String, - } - - test_parse_ok(&[ - ( - r#" - <?xml version="1.0" encoding="UTF-8"?> - <!DOCTYPE Envelope> - <Envelope> - <subject>Reference rates</subject> - </Envelope>"#, - Envelope { - subject: "Reference rates".to_string(), - }, - ), - ( - r#" - <?xml version="1.0" encoding="UTF-8"?> - <!DOCTYPE Envelope[]> - <Envelope> - <subject>Reference rates</subject> - </Envelope>"#, - Envelope { - subject: "Reference rates".to_string(), - }, - ), - ( - r#" - <?xml version="1.0" encoding="UTF-8"?> - <!DOCTYPE Envelope [ - <!ELEMENT subject (#PCDATA)> - ] > - <Envelope> - <subject>Reference rates</subject> - </Envelope>"#, - Envelope { - subject: "Reference rates".to_string(), - }, - ), - ]); -} - -#[test] -fn test_doctype_fail() { - let _ = simple_logger::init(); - #[derive(PartialEq, Serialize, Deserialize, Debug)] - struct Envelope { - subject: String, - } - - test_parse_err::<Envelope>(&[ - r#" - <?xml version="1.0" encoding="UTF-8"?> - <!DOCTYPE Envelope [ - <!ELEMENT subject (#PCDATA)> - > - <Envelope> - <subject>Reference rates</subject> - </Envelope>"#, - r#" - <?xml version="1.0" encoding="UTF-8"?> - <Envelope> - <subject>Reference rates</subject> - - <!DOCTYPE Envelope [ - <!ELEMENT subject (#PCDATA)> - ]> - - </Envelope>"#, - ]) -} - -#[test] -#[ignore] // FIXME -fn test_forwarded_namespace() { - #[derive(PartialEq, Serialize, Deserialize, Debug)] - struct Graphml { - #[serde(rename = "xsi:schemaLocation")] - schema_location: String, - } - let s = r#" - <?xml version="1.0" encoding="UTF-8"?> - <graphml xmlns="http://graphml.graphdrawing.org/xmlns" - xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xsi:schemaLocation="http://graphml.graphdrawing.org/xmlns - http://graphml.graphdrawing.org/xmlns/1.0/graphml.xsd"> - - - </graphml>"#; - test_parse_ok(&[( - s, - Graphml { - schema_location: "http://graphml.graphdrawing.org/xmlns - http://graphml.graphdrawing.org/xmlns/1.0/graphml.xsd" - .to_string(), - }, - )]); -} - -#[test] -fn test_parse_string() { - let _ = simple_logger::init(); - - test_parse_ok(&[ - ( - "<bla>This is a String</bla>", - "This is a String".to_string(), - ), - ("<bla></bla>", "".to_string()), - ("<bla> </bla>", "".to_string()), - ("<bla><boom/></bla>", "<boom/>".to_string()), - ("<bla>♫</bla>", "♫".to_string()), - ("<bla>♫</bla>", "♫".to_string()), - ( - "<bla>♫<![CDATA[<cookies/>]]>♫</bla>", - "♫<cookies/>♫".to_string(), - ), - ]); -} - -#[test] -#[ignore] // FIXME -fn test_parse_string_not_trim() { - let _ = simple_logger::init(); - - test_parse_ok(&[("<bla> </bla>", " ".to_string())]); -} - -#[test] -#[ignore] // FIXME -fn test_parse_enum() { - use self::Animal::*; - let _ = simple_logger::init(); - - test_parse_ok(&[ - ("<Animal xsi:type=\"Dog\"/>", Dog), - ( - "<Animal xsi:type=\"Frog\">Quak</Animal>", - Frog("Quak".to_string()), - ), - ( - "<Animal xsi:type=\"Ant\"><a/><c>bla</c><b>15</b><d>Foo</d></Animal>", - Ant(Simple { - a: (), - b: 15, - c: "bla".to_string(), - d: Some("Foo".to_string()), - }), - ), - ( - "<Animal xsi:type=\"Ant\"><a/><c>bla</c><b>15</b></Animal>", - Ant(Simple { - a: (), - b: 15, - c: "bla".to_string(), - d: None, - }), - ), - ( - "<Animal xsi:type=\"Cat\"><age>42</age><name>Shere Khan</name></Animal>", - Cat { - age: 42, - name: "Shere Khan".to_string(), - }, - ), - ]); - - #[derive(PartialEq, Debug, Serialize, Deserialize)] - struct Helper { - x: Animal, - } - - test_parse_ok(&[ - ("<Helper><x xsi:type=\"Dog\"/></Helper>", Helper { x: Dog }), - ( - "<Helper><x xsi:type=\"Frog\">Quak</Animal></Helper>", - Helper { - x: Frog("Quak".to_string()), - }, - ), - ( - "<Helper><x xsi:type=\"Cat\"> - <age>42</age> - <name>Shere Khan</name> - </x></Helper>", - Helper { - x: Cat { - age: 42, - name: "Shere Khan".to_string(), - }, - }, - ), - ]); -} - -#[test] -fn test_parse_i64() { - let _ = simple_logger::init(); - test_parse_ok(&[ - ("<bla>0</bla>", 0), - ("<bla>-2</bla>", -2), - ("<bla>-1234</bla>", -1234), - ("<bla> -1234 </bla>", -1234), - ]); -} - -#[test] -fn test_parse_u64() { - let _ = simple_logger::init(); - test_parse_ok(&[ - ("<bla>0</bla>", 0), - ("<bla>1234</bla>", 1234), - ("<bla> 1234 </bla>", 1234), - ]); -} - -#[test] -fn test_parse_bool_element() { - let _ = simple_logger::init(); - test_parse_ok(&[ - ("<bla>true</bla>", true), - ("<bla>false</bla>", false), - ("<bla> true </bla>", true), - ("<bla> false </bla>", false), - ("<bla>1</bla>", true), - ("<bla>0</bla>", false), - ]); - - test_parse_invalid::<bool>(&["<bla>verum</bla>"]); -} - -#[test] -fn test_parse_bool_attribute() { - #[derive(PartialEq, Debug, Deserialize, Serialize)] - struct Dummy { - foo: bool, - } - - let _ = simple_logger::init(); - test_parse_ok(&[ - ("<bla foo=\"true\"/>", Dummy { foo: true }), - ("<bla foo=\"false\"/>", Dummy { foo: false }), - ("<bla foo=\"1\"/>", Dummy { foo: true }), - ("<bla foo=\"0\"/>", Dummy { foo: false }), - ]); - - test_parse_invalid::<Dummy>(&[ - "<bla foo=\"bar\"/>", - "<bla foo=\" true \"/>", - "<bla foo=\"10\"/>", - "<bla foo=\"\"/>", - "<bla/>", - ]); -} - -#[test] -fn test_parse_unit() { - let _ = simple_logger::init(); - test_parse_ok(&[("<bla/>", ())]); -} - -#[test] -fn test_parse_f64() { - let _ = simple_logger::init(); - test_parse_ok(&[ - ("<bla>3.0</bla>", 3.0f64), - ("<bla>3.1</bla>", 3.1), - ("<bla>-1.2</bla>", -1.2), - ("<bla>0.4</bla>", 0.4), - ("<bla>0.4e5</bla>", 0.4e5), - ("<bla>0.4e15</bla>", 0.4e15), - ("<bla>0.4e-01</bla>", 0.4e-01), // precision troubles - ("<bla> 0.4e-01 </bla>", 0.4e-01), - ]); -} - -#[test] -fn test_parse_struct() { - let _ = simple_logger::init(); - - test_parse_ok(&[ - ( - "<Simple> - <c>abc</c> - <a/> - <b>2</b> - </Simple>", - Simple { - a: (), - b: 2, - c: "abc".to_string(), - d: None, - }, - ), - ( - "<Simple><!-- this is a comment --> - <c>abc</c> - <a/> - <b>2</b> - </Simple>", - Simple { - a: (), - b: 2, - c: "abc".to_string(), - d: None, - }, - ), - ( - "<Simple d=\"Foo\"><!-- this is a comment --> - <c>abc</c> - <a/> - <b>2</b> - </Simple>", - Simple { - a: (), - b: 2, - c: "abc".to_string(), - d: Some("Foo".to_string()), - }, - ), - ]); -} - -#[test] -fn test_option() { - let _ = simple_logger::init(); - test_parse_ok(&[ - ("<a/>", Some("".to_string())), - ("<a></a>", Some("".to_string())), - ("<a> </a>", Some("".to_string())), - ("<a>42</a>", Some("42".to_string())), - ]); -} - -#[test] -#[ignore] // FIXME -fn test_option_not_trim() { - let _ = simple_logger::init(); - test_parse_ok(&[("<a> </a>", Some(" ".to_string()))]); -} - -#[test] -fn test_amoskvin() { - let _ = simple_logger::init(); - #[derive(Debug, Deserialize, PartialEq, Serialize)] - struct Root { - foo: Vec<Foo>, - } - - #[derive(Debug, Deserialize, PartialEq, Serialize)] - struct Foo { - a: String, - b: Option<String>, - } - test_parse_ok(&[( - " -<root> -<foo> - <a>Hello</a> - <b>World</b> -</foo> -<foo> - <a>Hi</a> -</foo> -</root>", - Root { - foo: vec![ - Foo { - a: "Hello".to_string(), - b: Some("World".to_string()), - }, - Foo { - a: "Hi".to_string(), - b: None, - }, - ], - }, - )]); -} - -#[test] -#[ignore] // FIXME -fn test_nicolai86() { - let _ = simple_logger::init(); - #[derive(Serialize, Deserialize, PartialEq, Debug)] - struct TheSender { - name: String, - } - - #[derive(Serialize, Deserialize, PartialEq, Debug)] - struct CurrencyCube { - currency: String, - rate: String, - } - - #[derive(Serialize, Deserialize, PartialEq, Debug)] - #[allow(non_snake_case)] - struct InnerCube { - Cube: Vec<CurrencyCube>, - } - - #[derive(Serialize, Deserialize, PartialEq, Debug)] - #[allow(non_snake_case)] - struct OuterCube { - Cube: Vec<InnerCube>, - } - - #[derive(Serialize, Deserialize, PartialEq, Debug)] - #[allow(non_snake_case)] - struct Envelope { - subject: String, - Sender: TheSender, - Cube: OuterCube, - } - test_parse_ok(&[ - ( - r#" - <?xml version="1.0" encoding="UTF-8"?> - <gesmes:Envelope xmlns:gesmes="http://www.gesmes.org/xml/2002-08-01" xmlns="http://www.ecb.int/vocabulary/2002-08-01/eurofxref"> - <gesmes:subject>Reference rates</gesmes:subject> - <gesmes:Sender> - <gesmes:name>European Central Bank</gesmes:name> - </gesmes:Sender> - <Cube> </Cube> - </gesmes:Envelope>"#, - Envelope { - subject: "Reference rates".to_string(), - Sender: TheSender { - name: "European Central Bank".to_string(), - }, - Cube: OuterCube { Cube: vec![] }, - }, - ), - ( - r#" - <?xml version="1.0" encoding="UTF-8"?> - <gesmes:Envelope xmlns:gesmes="http://www.gesmes.org/xml/2002-08-01" xmlns="http://www.ecb.int/vocabulary/2002-08-01/eurofxref"> - <gesmes:subject>Reference rates</gesmes:subject> - <gesmes:Sender> - <gesmes:name>European Central Bank</gesmes:name> - </gesmes:Sender> - <Cube><Cube> - <Cube currency='GBP' rate='0.81725'/> - <Cube currency='Latinum' rate='999999'/> - </Cube></Cube> - </gesmes:Envelope>"#, - Envelope { - subject: "Reference rates".to_string(), - Sender: TheSender { - name: "European Central Bank".to_string(), - }, - Cube: OuterCube { - Cube: vec![InnerCube { - Cube: vec![ - CurrencyCube { - currency: "GBP".to_string(), - rate: "0.81725".to_string(), - }, - CurrencyCube { - currency: "Latinum".to_string(), - rate: "999999".to_string(), - }, - ], - }], - }, - }, - ), - ]); -} - -#[test] -fn test_hugo_duncan2() { - let _ = simple_logger::init(); - let s = r#" - <?xml version="1.0" encoding="UTF-8"?> - <DescribeVpcsResponse xmlns="http://ec2.amazonaws.com/doc/2014-10-01/"> - <requestId>8d521e9a-509e-4ef6-bbb7-9f1ac0d49cd1</requestId> - <vpcSet> - <item> - <vpcId>vpc-ba0d18d8</vpcId> - <state>available</state> - </item> - </vpcSet> - </DescribeVpcsResponse>"#; - #[derive(PartialEq, Debug, Serialize, Deserialize)] - #[allow(non_snake_case)] - struct VpcSet { - vpcId: String, - state: String, - } - - #[derive(PartialEq, Debug, Serialize)] - struct ItemVec<T>(Vec<T>); - - impl<'de, T: de::Deserialize<'de>> de::Deserialize<'de> for ItemVec<T> { - fn deserialize<D>(deserializer: D) -> Result<ItemVec<T>, D::Error> - where - D: de::Deserializer<'de>, - { - #[derive(PartialEq, Debug, Serialize, Deserialize)] - struct Helper<U> { - item: Vec<U>, - } - let h: Helper<_> = de::Deserialize::deserialize(deserializer)?; - Ok(ItemVec(h.item)) - } - } - #[derive(PartialEq, Debug, Serialize, Deserialize)] - #[allow(non_snake_case)] - struct DescribeVpcsResponse { - requestId: String, - vpcSet: ItemVec<VpcSet>, - } - test_parse_ok(&[( - s, - DescribeVpcsResponse { - requestId: "8d521e9a-509e-4ef6-bbb7-9f1ac0d49cd1".to_string(), - vpcSet: ItemVec(vec![VpcSet { - vpcId: "vpc-ba0d18d8".to_string(), - state: "available".to_string(), - }]), - }, - )]); -} - -#[test] -fn test_hugo_duncan() { - let _ = simple_logger::init(); - let s = " - <?xml version=\"1.0\" encoding=\"UTF-8\"?> - <DescribeInstancesResponse xmlns=\"http://ec2.amazonaws.com/doc/2014-10-01/\"> - <requestId>9474f558-10a5-42e8-84d1-f9ee181fe943</requestId> - <reservationSet/> - </DescribeInstancesResponse> - "; - #[derive(PartialEq, Debug, Serialize, Deserialize)] - #[allow(non_snake_case)] - struct DescribeInstancesResponse { - requestId: String, - reservationSet: (), - } - test_parse_ok(&[( - s, - DescribeInstancesResponse { - requestId: "9474f558-10a5-42e8-84d1-f9ee181fe943".to_string(), - reservationSet: (), - }, - )]); -} - -#[test] -fn test_parse_xml_value() { - let _ = simple_logger::init(); - #[derive(Eq, Debug, PartialEq, Deserialize, Serialize)] - struct Test { - #[serde(rename = "$value")] - myval: String, - } - test_parse_ok(&[( - "<Test>abc</Test>", - Test { - myval: "abc".to_string(), - }, - )]); -} - -#[test] -#[ignore] // FIXME -fn test_parse_complexstruct() { - let _ = simple_logger::init(); - - test_parse_ok(&[ - ( - "<Outer> - <inner> - <b>2</b> - <b>boom</b> - <b>88</b> - </inner> - </Outer>", - Outer { - inner: Some(Inner { - a: (), - b: (2, "boom".to_string(), 88), - c: vec![], - }), - }, - ), - ( - "<Outer> - <inner> - <c>abc</c> - <c>xyz</c> - <a/> - <b>2</b> - <b>boom</b> - <b>88</b> - </inner> - </Outer>", - Outer { - inner: Some(Inner { - a: (), - b: (2, "boom".to_string(), 88), - c: vec!["abc".to_string(), "xyz".to_string()], - }), - }, - ), - ("<Outer/>", Outer { inner: None }), - ]); -} - -#[test] -fn test_parse_attributes() { - let _ = simple_logger::init(); - - #[derive(PartialEq, Debug, Serialize, Deserialize)] - struct A { - a1: String, - #[serde(rename = "$value")] - a2: i32, - } - - test_parse_ok(&[( - r#"<A a1="What is the answer to the ultimate question?">42</A>"#, - A { - a1: "What is the answer to the ultimate question?".to_string(), - a2: 42, - }, - )]); - - #[derive(PartialEq, Debug, Serialize, Deserialize)] - struct B { - b1: String, - b2: i32, - } - - test_parse_ok(&[( - r#"<B b1="What is the answer to the ultimate question?" b2="42"/>"#, - B { - b1: "What is the answer to the ultimate question?".to_string(), - b2: 42, - }, - )]); - - #[derive(PartialEq, Debug, Serialize, Deserialize)] - struct C { - c1: B, - } - - test_parse_ok(&[ - ( - r#"<C><c1 b1="What is the answer to the ultimate question?" b2="42"/></C>"#, - C { - c1: B { - b1: "What is the answer to the ultimate question?".to_string(), - b2: 42, - }, - }, - ), - ( - r#"<C><c1 b1="What is the answer to the ultimate question?" b2="42"/> </C>"#, - C { - c1: B { - b1: "What is the answer to the ultimate question?".to_string(), - b2: 42, - }, - }, - ), - ( - r#"<C> <c1 b1="What is the answer to the ultimate question?" b2="42"> - </c1> </C>"#, - C { - c1: B { - b1: "What is the answer to the ultimate question?".to_string(), - b2: 42, - }, - }, - ), - ]); - - #[derive(PartialEq, Debug, Serialize, Deserialize)] - struct D { - d1: Option<A>, - } - test_parse_ok(&[( - r#"<D><d1 a1="What is the answer to the ultimate question?">42</d1></D>"#, - D { - d1: Some(A { - a1: "What is the answer to the ultimate question?".to_string(), - a2: 42, - }), - }, - )]); -} - -#[test] -#[ignore] // FIXME -fn test_parse_hierarchies() { - let _ = simple_logger::init(); - #[derive(PartialEq, Debug, Serialize, Deserialize)] - struct A { - a1: String, - a2: (String, String), - } - #[derive(PartialEq, Debug, Serialize, Deserialize)] - struct B { - b1: A, - b2: (A, A), - } - #[derive(PartialEq, Debug, Serialize, Deserialize)] - struct C { - c1: B, - c2: Vec<B>, - } - - test_parse_ok(&[ - ( - "<C><c1> - <b1> - <a1>No</a1> - <a2>Maybe</a2> - <a2>Yes</a2> - </b1> - <b2> - <a1>Red</a1> - <a2>Green</a2> - <a2>Blue</a2> - </b2> - <b2> - <a1>London</a1> - <a2>Berlin</a2> - <a2>Paris</a2> - </b2> - </c1></C>", - C { - c1: B { - b1: A { - a1: "No".to_string(), - a2: ("Maybe".to_string(), "Yes".to_string()), - }, - b2: ( - A { - a1: "Red".to_string(), - a2: ("Green".to_string(), "Blue".to_string()), - }, - A { - a1: "London".to_string(), - a2: ("Berlin".to_string(), "Paris".to_string()), - }, - ), - }, - c2: vec![], - }, - ), - ( - "<C><c1> - <b2> - <a2>Green</a2> - <a2>Blue</a2> - <a1>Red</a1> - </b2> - <b2> - <a2>Berlin</a2> - <a2>Paris</a2> - <a1>London</a1> - </b2> - <b1> - <a2>Maybe</a2> - <a2>Yes</a2> - <a1>No</a1> - </b1> - </c1></C>", - C { - c1: B { - b1: A { - a1: "No".to_string(), - a2: ("Maybe".to_string(), "Yes".to_string()), - }, - b2: ( - A { - a1: "Red".to_string(), - a2: ("Green".to_string(), "Blue".to_string()), - }, - A { - a1: "London".to_string(), - a2: ("Berlin".to_string(), "Paris".to_string()), - }, - ), - }, - c2: vec![], - }, - ), - ]); -} - -#[test] -fn unknown_field() { - #[derive(Deserialize, Debug, PartialEq, Eq, Serialize)] - struct A { - other: Vec<Other>, - } - - #[derive(Deserialize, Debug, PartialEq, Eq, Serialize)] - struct Other { - d: i32, - } - test_parse_ok(&[( - "<a> - <b> - <c>5</c> - </b> - <other> - <d>6</d> - </other> - </a>", - A { - other: vec![Other { d: 6 }], - }, - )]); -} - -// #[test] -// fn eoz() { -// use std::io::Read; -// let mut file = std::fs::File::open("Report_test.2.xml").unwrap(); -// let mut s = String::new(); -// file.read_to_string(&mut s).unwrap(); - -// let _xml_value: Element = from_str(&s).unwrap(); -// } - -#[test] -fn test_parse_unfinished() { - test_parse_err::<Simple>(&["<Simple> - <c>abc</c> - <a/> - <b>2</b> - <d/>"]); -} - -#[test] -fn test_things_qc_found() { - test_parse_err::<u32>(&["<\u{0}:/"]); -} - -#[test] -fn futile() { - let _ = simple_logger::init(); - #[derive(Eq, PartialEq, Debug, Serialize, Deserialize)] - struct Object { - id: u8, - name: String, - x: u8, - y: u8, - width: u8, - height: u8, - ellipse: Option<()>, - } - - test_parse_ok(&[ - ( - r###" - <object id="11" name="testEllipse" x="102" y="38" width="21" height="14"> - <ellipse/> - </object> - "###, - Object { - id: 11, - name: "testEllipse".to_owned(), - x: 102, - y: 38, - width: 21, - height: 14, - ellipse: Some(()), - }, - ), - ( - r###" - <object id="11" name="testEllipse" x="102" y="38" width="21" height="14"> - </object> - "###, - Object { - id: 11, - name: "testEllipse".to_owned(), - x: 102, - y: 38, - width: 21, - height: 14, - ellipse: None, - }, - ), - ]); -} - -#[test] -fn futile2() { - let _ = simple_logger::init(); - #[derive(Eq, PartialEq, Debug, Serialize, Deserialize)] - struct Null; - - #[derive(Eq, PartialEq, Debug, Serialize, Deserialize)] - struct Object { - field: Option<Null>, - }; - - #[derive(Eq, PartialEq, Debug, Serialize, Deserialize)] - struct Stuff { - stuff_field: Option<Object>, - }; - - test_parse_ok(&[ - ( - r###" - <object> - <field/> - </object> - "###, - Object { field: Some(Null) }, - ), - ( - r###" - <object> - </object> - "###, - Object { field: None }, - ), - ]); - - test_parse_ok(&[ - ( - r###" - <object> - <stuff_field/> - </object> - "###, - Stuff { - stuff_field: Some(Object { field: None }), - }, - ), - ( - r###" - <object> - <stuff_field> - <field/> - </stuff_field> - </object> - "###, - Stuff { - stuff_field: Some(Object { field: Some(Null) }), - }, - ), - ( - r###" - <object> - </object> - "###, - Stuff { stuff_field: None }, - ), - ( - r###" - <object/> - "###, - Stuff { stuff_field: None }, - ), - ]); -} - -#[test] -fn newtype_struct() { - #[derive(PartialEq, Debug, Serialize, Deserialize)] - struct Wrapper(String); - - test_parse_ok(&[( - r###"<wrapper>Content</wrapper>"###, - Wrapper("Content".into()), - )]); -} diff --git a/tests/readme.rs b/tests/readme.rs deleted file mode 100644 index 881d572..0000000 --- a/tests/readme.rs +++ /dev/null @@ -1,6 +0,0 @@ -extern crate docmatic; - -#[test] -fn test_readme() { - docmatic::assert_file("README.md"); -} diff --git a/tests/round_trip.rs b/tests/round_trip.rs deleted file mode 100644 index 54b3b53..0000000 --- a/tests/round_trip.rs +++ /dev/null @@ -1,110 +0,0 @@ -#[macro_use] -extern crate serde_derive; -extern crate serde; -extern crate serde_xml_rs; - -use serde::Deserialize; -use serde_xml_rs::{from_str, to_string, EventReader, ParserConfig}; - -#[derive(Debug, Serialize, Deserialize, PartialEq)] -struct Item { - name: String, - source: String, -} - - -#[derive(Debug, Serialize, Deserialize, PartialEq)] -enum Node { - Boolean(bool), - Identifier { value: String, index: u32 }, - EOF, -} - -#[derive(Debug, Serialize, Deserialize, PartialEq)] -struct Nodes { - #[serde(rename = "$value")] - items: Vec<Node>, -} - - -#[test] -fn basic_struct() { - let src = r#"<Item><name>Banana</name><source>Store</source></Item>"#; - let should_be = Item { - name: "Banana".to_string(), - source: "Store".to_string(), - }; - - let item: Item = from_str(src).unwrap(); - assert_eq!(item, should_be); - - let reserialized_item = to_string(&item).unwrap(); - assert_eq!(src, reserialized_item); -} - - -#[test] -#[ignore] -fn round_trip_list_of_enums() { - // Construct some inputs - let nodes = Nodes { - items: vec![ - Node::Boolean(true), - Node::Identifier { - value: "foo".to_string(), - index: 5, - }, - Node::EOF, - ], - }; - - let should_be = r#" - <Nodes> - <Boolean> - true - </Boolean> - <Identifier> - <value>foo</value> - <index>5</index> - </Identifier> - <EOF /> - </Nodes>"#; - - let serialized_nodes = to_string(&nodes).unwrap(); - assert_eq!(serialized_nodes, should_be); - - // Then turn it back into a `Nodes` struct and make sure it's the same - // as the original - let deserialized_nodes: Nodes = from_str(serialized_nodes.as_str()).unwrap(); - assert_eq!(deserialized_nodes, nodes); -} - -#[test] -fn whitespace_preserving_config() { - // Test a configuration which does not clip whitespace from tags - - let src = r#" - <Item> - <name> space banana </name> - <source> fantasy costco </source> - </Item>"#; - - let item_should_be = Item { - name: " space banana ".to_string(), - source: " fantasy costco ".to_string(), - }; - let config = ParserConfig::new() - .trim_whitespace(false) - .whitespace_to_characters(false); - let mut deserializer = - serde_xml_rs::Deserializer::new(EventReader::new_with_config(src.as_bytes(), config)); - - let item = Item::deserialize(&mut deserializer).unwrap(); - assert_eq!(item, item_should_be); - - // Space outside values is not preserved. - let serialized_should_be = - "<Item><name> space banana </name><source> fantasy costco </source></Item>"; - let reserialized_item = to_string(&item).unwrap(); - assert_eq!(reserialized_item, serialized_should_be); -} diff --git a/tests/test.rs b/tests/test.rs deleted file mode 100644 index 4b8ec86..0000000 --- a/tests/test.rs +++ /dev/null @@ -1,161 +0,0 @@ -#[macro_use] -extern crate serde_derive; -extern crate serde_xml_rs; - -extern crate log; -extern crate simple_logger; - -use serde_xml_rs::from_str; - -#[derive(Debug, Deserialize, PartialEq)] -struct Item { - name: String, - source: String, -} - -#[test] -fn simple_struct_from_attributes() { - let _ = simple_logger::init(); - - let s = r##" - <item name="hello" source="world.rs" /> - "##; - - let item: Item = from_str(s).unwrap(); - - assert_eq!( - item, - Item { - name: "hello".to_string(), - source: "world.rs".to_string(), - } - ); -} - -#[test] -fn multiple_roots_attributes() { - let _ = simple_logger::init(); - - let s = r##" - <item name="hello" source="world.rs" /> - <item name="hello" source="world.rs" /> - "##; - - let item: Vec<Item> = from_str(s).unwrap(); - - assert_eq!( - item, - vec![ - Item { - name: "hello".to_string(), - source: "world.rs".to_string(), - }, - Item { - name: "hello".to_string(), - source: "world.rs".to_string(), - }, - ] - ); -} - -#[test] -fn simple_struct_from_attribute_and_child() { - let _ = simple_logger::init(); - - let s = r##" - <item name="hello"> - <source>world.rs</source> - </item> - "##; - - let item: Item = from_str(s).unwrap(); - - assert_eq!( - item, - Item { - name: "hello".to_string(), - source: "world.rs".to_string(), - } - ); -} - -#[derive(Debug, Deserialize, PartialEq)] -struct Project { - name: String, - - #[serde(rename = "item", default)] - items: Vec<Item>, -} - -#[test] -fn nested_collection() { - let _ = simple_logger::init(); - - let s = r##" - <project name="my_project"> - <item name="hello1" source="world1.rs" /> - <item name="hello2" source="world2.rs" /> - </project> - "##; - - let project: Project = from_str(s).unwrap(); - - assert_eq!( - project, - Project { - name: "my_project".to_string(), - items: vec![ - Item { - name: "hello1".to_string(), - source: "world1.rs".to_string(), - }, - Item { - name: "hello2".to_string(), - source: "world2.rs".to_string(), - }, - ], - } - ); -} - -#[derive(Debug, Deserialize, PartialEq)] -enum MyEnum { - A(String), - B { name: String, flag: bool }, - C, -} - -#[derive(Debug, Deserialize, PartialEq)] -struct MyEnums { - #[serde(rename = "$value")] - items: Vec<MyEnum>, -} - -#[test] -fn collection_of_enums() { - let _ = simple_logger::init(); - - let s = r##" - <enums> - <A>test</A> - <B name="hello" flag="true" /> - <C /> - </enums> - "##; - - let project: MyEnums = from_str(s).unwrap(); - - assert_eq!( - project, - MyEnums { - items: vec![ - MyEnum::A("test".to_string()), - MyEnum::B { - name: "hello".to_string(), - flag: true, - }, - MyEnum::C, - ], - } - ); -} |