XML
facet-xml maps Facet types to XML via explicit field annotations. This showcase highlights common serialization patterns and the new diagnostic you get when a field forgets to declare its XML role.
Serialization
Attributes, elements, and Vec fields
Attributes live on the root } #[derive(Facet)]
struct Contact {
#[facet(xml::attribute)]
id: u32, }<ContactBook> tag while #[facet(xml::elements)] turns a Vec into repeated <contacts> children.Target Type
#[derive(Facet)]
#[facet(xml::ns_all)]
struct ContactBook {
#[facet(xml::attribute)]
owner: String,
<span style="color:#e0af68;">#</span><span style="color:#a9b1d6;">[</span><span style="color:#e0af68;">facet</span><span style="color:#a9b1d6;">(</span><span style="color:#e0af68;">xml</span><span style="color:#a9b1d6;">::</span><span style="color:#e0af68;">elements</span><span style="color:#a9b1d6;">)]</span>
<span style="color:#7aa2f7;">contacts</span><span style="color:#a9b1d6;">:</span> <span style="color:#2ac3de;">Vec</span><span style="color:#a9b1d6;"><</span><span style="color:#2ac3de;">Contact</span><span style="color:#a9b1d6;">>,</span>
<span style="color:#e0af68;">#</span><span style="color:#a9b1d6;">[</span><span style="color:#e0af68;">facet</span><span style="color:#a9b1d6;">(</span><span style="color:#e0af68;">xml</span><span style="color:#a9b1d6;">::</span><span style="color:#e0af68;">element</span><span style="color:#a9b1d6;">)]</span>
<span style="color:#7aa2f7;">name</span><span style="color:#a9b1d6;">:</span> <span style="color:#2ac3de;">String</span><span style="color:#a9b1d6;">,</span>
<span style="color:#e0af68;">#</span><span style="color:#a9b1d6;">[</span><span style="color:#e0af68;">facet</span><span style="color:#a9b1d6;">(</span><span style="color:#e0af68;">xml</span><span style="color:#a9b1d6;">::</span><span style="color:#e0af68;">element</span><span style="color:#a9b1d6;">)]</span>
<span style="color:#7aa2f7;">email</span><span style="color:#a9b1d6;">:</span> <span style="color:#2ac3de;">Option</span><span style="color:#a9b1d6;"><</span><span style="color:#2ac3de;">String</span><span style="color:#a9b1d6;">>,</span>
Value Input
ContactBook {
owner: "Operations",
contacts: Vec<Contact> [
Contact {
id: 1,
name: "Alice",
email: Option::Some("alice@example.com"),
},
Contact {
id: 2,
name: "Bob",
email: Option::None,
},
],
}XML Output
<ContactBook xmlns="https://example.com/contacts" owner="Operations">
<Contact id="1">
<name>Alice</name>
<email>alice@example.com</email>
</Contact>
<Contact id="2">
<name>Bob</name>
</Contact>
</ContactBook>
xml::text for content
#[facet(xml::text)] captures character data inside an element, while attributes remain on the tag. This scenario deserializes the feed and pretty-prints the resulting Facet value.
XML Input
<AlertFeed severity="warning">
<title>System Notices</title>
<messages code="OPS-201">Deploying new release at 02:00 UTC</messages>
<messages code="DB-503">Database failover test scheduled</messages>
</AlertFeed>Target Type
#[derive(Facet)]
struct AlertFeed {
#[facet(xml::attribute)]
severity: String,
<span style="color:#e0af68;">#</span><span style="color:#a9b1d6;">[</span><span style="color:#e0af68;">facet</span><span style="color:#a9b1d6;">(</span><span style="color:#e0af68;">xml</span><span style="color:#a9b1d6;">::</span><span style="color:#e0af68;">element</span><span style="color:#a9b1d6;">)]</span>
<span style="color:#7aa2f7;">title</span><span style="color:#a9b1d6;">:</span> <span style="color:#2ac3de;">String</span><span style="color:#a9b1d6;">,</span>
<span style="color:#e0af68;">#</span><span style="color:#a9b1d6;">[</span><span style="color:#e0af68;">facet</span><span style="color:#a9b1d6;">(</span><span style="color:#e0af68;">xml</span><span style="color:#a9b1d6;">::</span><span style="color:#e0af68;">elements</span><span style="color:#a9b1d6;">)]</span>
<span style="color:#7aa2f7;">messages</span><span style="color:#a9b1d6;">:</span> <span style="color:#2ac3de;">Vec</span><span style="color:#a9b1d6;"><</span><span style="color:#2ac3de;">AlertMessage</span><span style="color:#a9b1d6;">>,</span>
}
#[derive(Facet)]
struct AlertMessage {
#[facet(xml::attribute)]
code: String,
<span style="color:#e0af68;">#</span><span style="color:#a9b1d6;">[</span><span style="color:#e0af68;">facet</span><span style="color:#a9b1d6;">(</span><span style="color:#e0af68;">xml</span><span style="color:#a9b1d6;">::</span><span style="color:#e0af68;">text</span><span style="color:#a9b1d6;">)]</span>
<span style="color:#7aa2f7;">body</span><span style="color:#a9b1d6;">:</span> <span style="color:#2ac3de;">String</span><span style="color:#a9b1d6;">,</span>
}
Success
AlertFeed {
severity: "warning",
title: "System Notices",
messages: Vec<AlertMessage> [
AlertMessage {
code: "OPS-201",
body: "Deploying new release at 02:00 UTC",
},
AlertMessage {
code: "DB-503",
body: "Database failover test scheduled",
},
],
}Diagnostics
Missing XML annotations
Every field must opt into XML via }#[facet(xml::attribute/element/...)] (or #[facet(child)]). Leaving a field unannotated now produces a descriptive error before serialization begins.Target Type
#[derive(Facet)]
struct MissingXmlAnnotations {
title: String,
<span style="color:#7aa2f7;">details</span><span style="color:#a9b1d6;">:</span> <span style="color:#2ac3de;">String</span><span style="color:#a9b1d6;">,</span>
Value Input
MissingXmlAnnotations {
title: "Weekly Report",
details: "Compile-time errors per crate",
}Error
xml::missing_xml_annotations
× MissingXmlAnnotations cannot serialize because these fields lack XML annotations: title: String, details: String. Each field must opt into XML via one of:
│ • #[facet(xml::attribute)] → <MissingXmlAnnotations field="…" /> (attributes)
│ • #[facet(xml::element)] → <MissingXmlAnnotations><field>…</field></MissingXmlAnnotations> (single child)
│ • #[facet(xml::elements)] → <MissingXmlAnnotations><field>…</field>…</MissingXmlAnnotations> (lists of children)
│ • #[facet(xml::text)] → <MissingXmlAnnotations>…</MissingXmlAnnotations> (text content)
│ • #[facet(xml::element_name)] to capture the element/tag name itself.
│ `#[facet(child)]` is accepted as shorthand for xml::element. Use #[facet(flatten)] or #[facet(skip*)] if the field should be omitted.