Skip to content

Commit

Permalink
📝 more usage examples (#162)
Browse files Browse the repository at this point in the history
  • Loading branch information
punkstarman authored Sep 17, 2021
1 parent 6902657 commit 4a3b6bd
Show file tree
Hide file tree
Showing 3 changed files with 148 additions and 58 deletions.
63 changes: 17 additions & 46 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,61 +2,32 @@

[![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+)
`xml-rs` based deserializer for Serde (compatible with 1.0)

## 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:
## Example usage

```rust
#[macro_use]
extern crate serde_derive;
extern crate serde;
extern crate serde_xml_rs;

use serde_xml_rs::from_reader;
use serde;
use serde_derive::{Deserialize, Serialize};
use serde_xml_rs::{from_str, to_string};

#[derive(Debug, Deserialize)]
#[derive(Debug, Serialize, Deserialize, PartialEq)]
struct Item {
pub name: String,
pub source: String
}

#[derive(Debug, Deserialize)]
struct Project {
pub name: String,

#[serde(rename = "Item", default)]
pub items: Vec<Item>
name: String,
source: String,
}

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
let src = r#"<Item><name>Banana</name><source>Store</source></Item>"#;
let should_be = Item {
name: "Banana".to_string(),
source: "Store".to_string(),
};

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`:
let item: Item = from_str(src).unwrap();
assert_eq!(item, should_be);

```rust,ignore
struct Foo {
pub abc: String,
#[serde(rename = "$value")]
pub body: String,
let reserialized_item = to_string(&item).unwrap();
assert_eq!(src, reserialized_item);
}
```

## 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.
137 changes: 131 additions & 6 deletions src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,56 @@
//! # Serde XML
//!
//! XML is a flexible markup language that is still used for sharing data between applications or
//! for writing configuration files.
//!
//! # Examples
//! Serde XML provides a way to convert between text and strongly-typed Rust data structures.
//!
//! ```rust
//! extern crate serde;
//! extern crate serde_xml_rs;
//! ## 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.
//!
//! #[macro_use]
//! extern crate serde_derive;
//! For example, encoding the following document in YAML is not trivial.
//!
//! ```xml
//! <document>
//! <header>A header</header>
//! <section>First section</section>
//! <section>Second section</section>
//! <sidenote>A sidenote</sidenote>
//! <section>Third section</section>
//! <sidenote>Another sidenote</sidenote>
//! <section>Fourth section</section>
//! <footer>The footer</footer>
//! </document>
//! ```
//!
//! 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;
//! use serde_derive::{Deserialize, Serialize};
//! use serde_xml_rs::{from_str, to_string};
//!
//! #[derive(Debug, Serialize, Deserialize, PartialEq)]
Expand All @@ -31,6 +73,89 @@
//! assert_eq!(src, reserialized_item);
//! }
//! ```
//!
//! ## Tag contents
//!
//! ```rust
//! # use serde;
//! # use serde_derive::{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#"<document><content>Lorem ipsum</content></document>"#;
//! let document: Document = from_str(src).unwrap();
//! assert_eq!(document.content.value, "Lorem ipsum");
//! }
//! ```
//!
//! ## Repeated tags
//!
//! ```rust
//! # use serde;
//! # use serde_derive::{Deserialize, Serialize};
//! # use serde_xml_rs::{from_str, to_string};
//!
//! #[derive(Debug, Serialize, Deserialize, PartialEq)]
//! struct PlateAppearance {
//! #[serde(rename = "$value")]
//! events: Vec<Event>
//! }
//!
//! #[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<Base>, 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#"
//! <plate-appearance>
//! <pitch speed="95" type="FourSeam" outcome="Ball" />
//! <pitch speed="91" type="FourSeam" outcome="Strike" />
//! <pitch speed="85" type="Changeup" outcome="Ball" />
//! <runner from="First" to="Second" outcome="Steal" />
//! <pitch speed="89" type="Slider" outcome="Strike" />
//! <pitch speed="88" type="Curve" outcome="Hit" />
//! </plate-appearance>"#;
//! 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 }));
//! }
//! ```
pub mod de;
mod error;
Expand Down
6 changes: 0 additions & 6 deletions tests/readme.rs

This file was deleted.

0 comments on commit 4a3b6bd

Please sign in to comment.