18 stable releases

1.36.0 Mar 13, 2024
1.27.0 Sep 1, 2023
1.25.0 May 26, 2023
1.21.0 Dec 17, 2022
0.6.3 Jul 5, 2022

#238 in Parser implementations

Download history 566/week @ 2024-03-16 1361/week @ 2024-03-23 548/week @ 2024-03-30 626/week @ 2024-04-06 774/week @ 2024-04-13 706/week @ 2024-04-20 770/week @ 2024-04-27 559/week @ 2024-05-04 463/week @ 2024-05-11 692/week @ 2024-05-18 414/week @ 2024-05-25 676/week @ 2024-06-01 651/week @ 2024-06-08 623/week @ 2024-06-15 648/week @ 2024-06-22 1055/week @ 2024-06-29

3,061 downloads per month
Used in 18 crates (5 directly)

MIT license

52KB
946 lines

hard-xml

Strong typed xml, based on xmlparser.

This is a fork of https://github.com/PoiScript/strong-xml as it has become unmaintained.

Crates.io Document

Quick Start

cargo add hard-xml
use std::borrow::Cow;
use hard_xml::{XmlRead, XmlWrite};

#[derive(XmlWrite, XmlRead, PartialEq, Debug)]
#[xml(tag = "parent")]
struct Parent<'a> {
    #[xml(attr = "attr1")]
    attr1: Cow<'a, str>,
    #[xml(attr = "attr2")]
    attr2: Option<Cow<'a, str>>,
    #[xml(child = "child")]
    child: Vec<Child<'a>>,
}

#[derive(XmlWrite, XmlRead, PartialEq, Debug)]
#[xml(tag = "child")]
struct Child<'a> {
    #[xml(text)]
    text: Cow<'a, str>,
}

assert_eq!(
    (Parent { attr1: "val".into(), attr2: None, child: vec![] }).to_string().unwrap(),
    r#"<parent attr1="val"/>"#
);

assert_eq!(
    Parent::from_str(r#"<parent attr1="val" attr2="val"><child></child></parent>"#).unwrap(),
    Parent { attr1: "val".into(), attr2: Some("val".into()), child: vec![Child { text: "".into() }] }
);

Attributes

#[xml(tag = "")]

Specifies the xml tag of a struct or an enum variant.

#[derive(XmlWrite, XmlRead, PartialEq, Debug)]
#[xml(tag = "parent")]
struct Parent {}

assert_eq!(
    (Parent {}).to_string().unwrap(),
    r#"<parent/>"#
);

assert_eq!(
    Parent::from_str(r#"<parent/>"#).unwrap(),
    Parent {}
);
#[derive(XmlWrite, XmlRead, PartialEq, Debug)]
#[xml(tag = "tag1")]
struct Tag1 {}

#[derive(XmlWrite, XmlRead, PartialEq, Debug)]
#[xml(tag = "tag2")]
struct Tag2 {}

#[derive(XmlWrite, XmlRead, PartialEq, Debug)]
enum Tag {
    #[xml(tag = "tag1")]
    Tag1(Tag1),
    #[xml(tag = "tag2")]
    Tag2(Tag2),
}

assert_eq!(
    (Tag::Tag1(Tag1 {})).to_string().unwrap(),
    r#"<tag1/>"#
);

assert_eq!(
    Tag::from_str(r#"<tag2></tag2>"#).unwrap(),
    Tag::Tag2(Tag2 {})
);

#[xml(attr = "")]

Specifies that a struct field is attribute. Support Cow<str>, Option<Cow<str>>, T and Option<T> where T: FromStr + Display.

use hard_xml::{XmlRead, XmlWrite};

#[derive(XmlWrite, XmlRead, PartialEq, Debug)]
#[xml(tag = "parent")]
struct Parent {
    #[xml(attr = "attr")]
    attr: usize
}

assert_eq!(
    (Parent { attr: 42 }).to_string().unwrap(),
    r#"<parent attr="42"/>"#
);

assert_eq!(
    Parent::from_str(r#"<parent attr="48"></parent>"#).unwrap(),
    Parent { attr: 48 }
);

#[xml(child = "")]

Specifies that a struct field is a child element. Support T, Option<T>, Vec<T> where T: XmlRead + XmlWrite.

use hard_xml::{XmlRead, XmlWrite};

#[derive(XmlWrite, XmlRead, PartialEq, Debug)]
#[xml(tag = "tag1")]
struct Tag1 {}

#[derive(XmlWrite, XmlRead, PartialEq, Debug)]
#[xml(tag = "tag2")]
struct Tag2 {}

#[derive(XmlWrite, XmlRead, PartialEq, Debug)]
#[xml(tag = "tag3")]
struct Tag3 {}

#[derive(XmlWrite, XmlRead, PartialEq, Debug)]
enum Tag12 {
    #[xml(tag = "tag1")]
    Tag1(Tag1),
    #[xml(tag = "tag2")]
    Tag2(Tag2),
}

#[derive(XmlWrite, XmlRead, PartialEq, Debug)]
#[xml(tag = "parent")]
struct Parent {
    #[xml(child = "tag3")]
    tag3: Vec<Tag3>,
    #[xml(child = "tag1", child = "tag2")]
    tag12: Option<Tag12>
}

assert_eq!(
    (Parent { tag3: vec![Tag3 {}], tag12: None }).to_string().unwrap(),
    r#"<parent><tag3/></parent>"#
);

assert_eq!(
    Parent::from_str(r#"<parent><tag2></tag2></parent>"#).unwrap(),
    Parent { tag3: vec![], tag12: Some(Tag12::Tag2(Tag2 {})) }
);

#[xml(text)]

Specifies that a struct field is text content. Support Cow<str>, Vec<Cow<str>>, Option<Cow<str>>, T, Vec<T>, Option<T> where T: FromStr + Display.

use std::borrow::Cow;
use hard_xml::{XmlRead, XmlWrite};

#[derive(XmlWrite, XmlRead, PartialEq, Debug)]
#[xml(tag = "parent")]
struct Parent<'a> {
    #[xml(text)]
    content: Cow<'a, str>,
}

assert_eq!(
    (Parent { content: "content".into() }).to_string().unwrap(),
    r#"<parent>content</parent>"#
);

assert_eq!(
    Parent::from_str(r#"<parent></parent>"#).unwrap(),
    Parent { content: "".into() }
);

#[xml(flatten_text = "")]

Specifies that a struct field is child text element. Support Cow<str>, Vec<Cow<str>>, Option<Cow<str>>, T, Vec<T>, Option<T> where T: FromStr + Display.

use std::borrow::Cow;
use hard_xml::{XmlRead, XmlWrite};

#[derive(XmlWrite, XmlRead, PartialEq, Debug)]
#[xml(tag = "parent")]
struct Parent<'a> {
    #[xml(flatten_text = "child")]
    content: Cow<'a, str>,
}

assert_eq!(
    (Parent { content: "content".into() }).to_string().unwrap(),
    r#"<parent><child>content</child></parent>"#
);

assert_eq!(
    Parent::from_str(r#"<parent><child></child></parent>"#).unwrap(),
    Parent { content: "".into() }
);

#[xml(cdata)]

Specifies a CDATA text. Should be used together with text or flatten_text.

#[xml(cdata)] only changes the behavior of writing, text field without #[xml(cdata)] can still works with cdata tag.

use std::borrow::Cow;
use hard_xml::{XmlRead, XmlWrite};

#[derive(XmlWrite, XmlRead, PartialEq, Debug)]
#[xml(tag = "parent")]
struct Parent<'a> {
    #[xml(text, cdata)]
    content: Cow<'a, str>,
}

assert_eq!(
    (Parent { content: "content".into() }).to_string().unwrap(),
    r#"<parent><![CDATA[content]]></parent>"#
);
use std::borrow::Cow;
use hard_xml::{XmlRead, XmlWrite};

#[derive(XmlWrite, XmlRead, PartialEq, Debug)]
#[xml(tag = "parent")]
struct Parent<'a> {
    #[xml(flatten_text = "code", cdata)]
    content: Cow<'a, str>,
}

assert_eq!(
    (Parent { content: r#"hello("deities!");"#.into() }).to_string().unwrap(),
    r#"<parent><code><![CDATA[hello("deities!");]]></code></parent>"#
);

#[xml(default)]

Use Default::default() if the value is not present when reading.

use std::borrow::Cow;
use hard_xml::XmlRead;

#[derive(XmlRead, PartialEq, Debug)]
#[xml(tag = "root")]
struct Root {
    #[xml(default, attr = "attr")]
    attr: bool,
}

assert_eq!(
    Root::from_str(r#"<root/>"#).unwrap(),
    Root { attr: false }
);

assert_eq!(
    Root::from_str(r#"<root attr="1"/>"#).unwrap(),
    Root { attr: true }
);

License

MIT

License: MIT

Dependencies

~2MB
~45K SLoC