xmpp-rs-mirror/xso/src/from_xml_doc.md
Jonas Schäfer 4d1166b66d xso-proc: allow paths as XML names
Not sure if this is something useful to have, but it feels consistent
with `namespace`.
2024-06-23 12:40:18 +02:00

2 KiB

Make a struct or enum parseable from XML

This derives the [FromXml] trait on a struct or enum. It is the counterpart to [macro@IntoXml].

Example

# use xso::FromXml;
static MY_NAMESPACE: &str = "urn:example";

#[derive(FromXml, Debug, PartialEq)]
#[xml(namespace = MY_NAMESPACE, name = "foo")]
struct Foo;

let foo: Foo = xso::from_bytes(b"<foo xmlns='urn:example'/>").unwrap();
assert_eq!(foo, Foo);

Attributes

The derive macros need to know which XML namespace and name the elements it is supposed have. This must be specified via key-value pairs on the type the derive macro is invoked on. These are specified as Rust attributes. In order to disambiguate between XML attributes and Rust attributes, we are going to refer to Rust attributes using the term meta instead, which is consistent with the Rust language reference calling that syntax construct meta.

All key-value pairs interpreted by these derive macros must be wrapped in a #[xml( ... )] meta. The following keys are defined on structs:

Key Value type Description
namespace path The path to a &'static str which holds the XML namespace to match.
name string literal or path The XML element name to match. If it is a path, it must point at a &'static NcNameStr.

Note that the name value must be a valid XML element name, without colons. The namespace prefix, if any, is assigned automatically at serialisation time and cannot be overridden. The following will thus not compile:

# use xso::FromXml;
# static MY_NAMESPACE: &'static str = "urn:example";
#[derive(FromXml, Debug, PartialEq)]
#[xml(namespace = MY_NAMESPACE, name = "fnord:foo")]  // colon not allowed
struct Foo;

Limitations

Supports only empty structs currently. For example, the following will not work:

# use xso::FromXml;
# static MY_NAMESPACE: &str = "urn:example";
#[derive(FromXml, Debug, PartialEq)]
#[xml(namespace = MY_NAMESPACE, name = "foo")]
struct Foo {
    some_field: String,
}