//! # Serde XML
//!
//! XML is a flexible markup language that is still used for sharing data between applications or
//! for writing configuration files.
//!
//! Serde XML provides a way to convert between text and strongly-typed Rust data structures.
//!
//! ## Caveats
//!
//! The Serde framework was mainly designed with formats such as JSON or YAML in mind.
//! As opposed to XML, these formats have the advantage of a stricter syntax which makes it
//! possible to know what type a field is without relying on an accompanying schema,
//! and disallows repeating the same tag multiple times in the same object.
//!
//! For example, encoding the following document in YAML is not trivial.
//!
//! ```xml
//!
//!
//!
//!
//! A sidenote
//!
//! Another sidenote
//!
//!
//!
//! ```
//!
//! One possibility is the following YAML document.
//!
//! ```yaml
//! - header: A header
//! - section: First section
//! - section: Second section
//! - sidenote: A sidenote
//! - section: Third section
//! - sidenote: Another sidenote
//! - section: Fourth section
//! - footer: The footer
//! ```
//!
//! Other notable differences:
//! - XML requires a named root node.
//! - XML has a namespace system.
//! - XML distinguishes between attributes, child tags and contents.
//! - In XML, the order of nodes is sometimes important.
//!
//! ## Basic example
//!
//! ```rust
//! use serde::{Deserialize, Serialize};
//! use serde_xml_rs::{from_str, to_string};
//!
//! #[derive(Debug, Serialize, Deserialize, PartialEq)]
//! struct Item {
//! name: String,
//! source: String,
//! }
//!
//! fn main() {
//! let src = r#"- BananaStore
"#;
//! 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);
//! }
//! ```
//!
//! ## Tag contents
//!
//! ```rust
//! # use serde::{Deserialize, Serialize};
//! # use serde_xml_rs::{from_str, to_string};
//!
//! #[derive(Debug, Serialize, Deserialize, PartialEq)]
//! struct Document {
//! content: Content
//! }
//!
//! #[derive(Debug, Serialize, Deserialize, PartialEq)]
//! struct Content {
//! #[serde(rename = "$value")]
//! value: String
//! }
//!
//! fn main() {
//! let src = r#"Lorem ipsum"#;
//! let document: Document = from_str(src).unwrap();
//! assert_eq!(document.content.value, "Lorem ipsum");
//! }
//! ```
//!
//! ## Repeated tags
//!
//! ```rust
//! # use serde::{Deserialize, Serialize};
//! # use serde_xml_rs::{from_str, to_string};
//!
//! #[derive(Debug, Serialize, Deserialize, PartialEq)]
//! struct PlateAppearance {
//! #[serde(rename = "$value")]
//! events: Vec
//! }
//!
//! #[derive(Debug, Serialize, Deserialize, PartialEq)]
//! #[serde(rename_all = "kebab-case")]
//! enum Event {
//! Pitch(Pitch),
//! Runner(Runner),
//! }
//!
//! #[derive(Debug, Serialize, Deserialize, PartialEq)]
//! struct Pitch {
//! speed: u32,
//! r#type: PitchType,
//! outcome: PitchOutcome,
//! }
//!
//! #[derive(Debug, Serialize, Deserialize, PartialEq)]
//! enum PitchType { FourSeam, TwoSeam, Changeup, Cutter, Curve, Slider, Knuckle, Pitchout }
//!
//! #[derive(Debug, Serialize, Deserialize, PartialEq)]
//! enum PitchOutcome { Ball, Strike, Hit }
//!
//! #[derive(Debug, Serialize, Deserialize, PartialEq)]
//! struct Runner {
//! from: Base, to: Option, outcome: RunnerOutcome,
//! }
//!
//! #[derive(Debug, Serialize, Deserialize, PartialEq)]
//! enum Base { First, Second, Third, Home }
//! #[derive(Debug, Serialize, Deserialize, PartialEq)]
//! enum RunnerOutcome { Steal, Caught, PickOff }
//!
//! fn main() {
//! let document = r#"
//!
//!
//!
//!
//!
//!
//!
//! "#;
//! let plate_appearance: PlateAppearance = from_str(document).unwrap();
//! assert_eq!(plate_appearance.events[0], Event::Pitch(Pitch { speed: 95, r#type: PitchType::FourSeam, outcome: PitchOutcome::Ball }));
//! }
//! ```
//!
//! ## Custom EventReader
//!
//! ```rust
//! use serde::{Deserialize, Serialize};
//! use serde_xml_rs::{from_str, to_string, de::Deserializer};
//! use xml::reader::{EventReader, ParserConfig};
//!
//! #[derive(Debug, Serialize, Deserialize, PartialEq)]
//! struct Item {
//! name: String,
//! source: String,
//! }
//!
//! fn main() {
//! let src = r#"- Banana Store
"#;
//! let should_be = Item {
//! name: " Banana ".to_string(),
//! source: "Store".to_string(),
//! };
//!
//! let config = ParserConfig::new()
//! .trim_whitespace(false)
//! .whitespace_to_characters(true);
//! let event_reader = EventReader::new_with_config(src.as_bytes(), config);
//! let item = Item::deserialize(&mut Deserializer::new(event_reader)).unwrap();
//! assert_eq!(item, should_be);
//! }
//! ```
//!
pub mod de;
mod error;
pub mod ser;
pub use crate::de::{from_reader, from_str, Deserializer};
pub use crate::error::Error;
pub use crate::ser::{to_string, to_writer, Serializer};
pub use xml::reader::{EventReader, ParserConfig};