Expand description

This crate provides a macro to provide automatic deserialization of structs from XML.

Note: the implementation is highly limited and inelegant. I wrote this purely to help power a feed reader I’m working on as a personal project; don’t expect anything “production-ready…” (See the caveats below.)

Examples

Basic

Here’s how you could use this crate to easily parse a very simple XML structure:

use deserialize_xml::DeserializeXml;

#[derive(Default, Debug, DeserializeXml)]
struct StringOnly {
    title: String,
    author: String,
}

let input = "<stringonly><title>Title</title><author>Author</author></stringonly>";
// `from_str` here was provided by `#[derive(DeserializeXml)]` above
let result = StringOnly::from_str(input).unwrap();
assert_eq!(result.title, "Title");
assert_eq!(result.author, "Author");

Advanced

This example shows more advanced functionality:

use deserialize_xml::DeserializeXml;

#[derive(Default, Debug, DeserializeXml)]
// This attribute indicates we should parse this struct upon encountering an <item> tag
#[deserialize_xml(tag = "item")]
struct StringOnly {
    title: String,
    author: String,
}

#[derive(Default, Debug, DeserializeXml)]
struct Channel {
    title: String,
    // This allows us to use an idiomatic name for the
    // struct member instead of the raw tag name
    #[deserialize_xml(tag = "lastUpdated")]
    last_updated: String,
    ttl: u32,
    // (unfortunately, we need to repeat `tag = "item"` here for now)
    #[deserialize_xml(tag = "item")]
    entries: Vec<StringOnly>,
}

let input = r#"<channel>
      <title>test channel please ignore</title>
      <lastUpdated>2022-09-22</lastUpdated>
      <ttl>3600</ttl>
      <item><title>Article 1</title><author>Guy</author></item>
      <item><title>Article 2</title><author>Dudette</author></item>
    </channel>"#;

let result = Channel::from_str(input).unwrap();
assert_eq!(result.title, "test channel please ignore");
assert_eq!(result.ttl, 3600);
assert_eq!(result.entries.len(), 2);
assert_eq!(result.entries[0].title, "Article 1");
assert_eq!(result.entries[0].author, "Guy");
assert_eq!(result.entries[1].title, "Article 2");
assert_eq!(result.entries[1].author, "Dudette");

Caveats

  • The support for Vec<T> is very limited at the moment. Namely, the macro performs a textual check to see if the member type is Vec<T>; if so, it creates an empty vec and pushes the results of DeserializeXml::from_reader for the inner type (T) when it encounters the matching tag. Note the emphasis on textual check: the macro will fail if you “spell” Vec<T> differently (e.g., by aliasing it), or use your own container type.

  • The macro only supports structs.

  • An implementation of the DeserializeXml trait is provided for Strings and numeric types (i.e. u8, i8, …). To add support for your own type, see this section.

Implementing DeserializeXml for your own struct

See the implementation of DeserializeXml for String for an example.

Structs

Traits

Type Definitions

Derive Macros