Expand description
Bumpalo-backed, libxml2-shaped DOM.
This is the v2 tree representation that replaces the per-node-malloc
design in [crate::node]. It’s not wired into the parser yet — that
happens in Milestone 2. Until then, the rest of the codebase keeps using
the existing [crate::node] types unchanged.
§Design
-
One arena per document. A
bumpalo::Bumpowns all node, attribute, namespace, and string allocations. Per-node alloc cost drops to a pointer bump; drop is free per node — the whole arena is freed at once. -
libxml2-shaped nodes. A single
Nodestruct (not a Rust enum) with aNodeKindtag and inline fields for every variant. Children form a doubly-linked list viafirst_child/last_childon the parent andnext_sibling/prev_sibling+parenton each child. Attributes form their own doubly-linked list on the element. Field offsets and semantics mirrorxmlNodeso a futureextern "C"shim can expose the same memory to libxml2 callers verbatim. -
Cell-of-references for links. All sibling/child/parent pointers are
Cell<Option<&'doc Node<'doc>>>. This is the standard idiomatic pattern for graph-shaped data in an arena: you get mutation withoutRefCelloverhead and without raw pointers in the public API. -
Strings borrowed where possible. Names and text contents are
&'doc str. When the parser can borrow from the source slice directly it does; otherwise it allocates a copy in the arena. NoArc<str>per name.
§The self-referential Document wrapper
Document owns a Bump and holds a root pointer (&Node) into that
same Bump. That’s a self-referential struct, which safe Rust doesn’t
express directly. The arena nodes have stable addresses (bumpalo never
relocates allocations), so the references are sound in principle. We
encode it with one contained unsafe block in Document::root, audited by:
- The
Bumpis stored in anArc<Bump>— heap-allocated, never moved while any clone of the Arc lives. C-ABI consumers (sup-xml-compat) share a single thread-local arena across every document, so cross-doc node grafts (libxml2 consumers like lxml moving nodes between documents) are safe by construction — node memory outlives any individual doc. - The root pointer is built from
&Bump::alloc(...)of the sameBump, so the lifetime is genuinely'self(as in: tied to theDocument). - The
Document’s public methods hand out references with a borrow of&self, which the borrow checker treats as'self-bounded. Outside those methods, no'docreference can escape.
See Document for the API.
Structs§
- Attr
Iter - Iterator over an element’s attributes.
- Attribute
- An attribute on an element. Belongs to a doubly-linked list rooted at
Node::first_attribute/Node::last_attributeon its owning element. - Child
Iter - Iterator over a node’s children.
- Document
Documentowns aBumpand a pointer to the rootNodeinside thatBump. The struct is self-referential and the unsafety is contained — see the module-level docs for the safety argument.- Document
Builder - Constructs a
Documentone node at a time. The parser uses this internally; consumers building trees by hand use the same. - Html
Doctype - Captured DOCTYPE content from an HTML document. Stored verbatim; HTML5 does not validate against DTDs, but the public/system identifiers are surfaced for tools that want to introspect them (e.g. detecting XHTML vs HTML5 input).
- Html
Meta - HTML-specific document metadata. Set when the document came from
parse_html_*;Nonefor XML documents. - Namespace
- A namespace binding (
prefix → href). Lifetime-bound to the document’s arena. - Node
- A node in the XML tree. One struct for every kind; fields are used per-kind.
- Unparsed
Entity - An owned XML document with an arena-allocated tree.
Enums§
- Node
Kind - Discriminant for
Node::kind. - NsDecl
Iter - Iterator yielded by
Node::ns_declarations. Each item is(prefix, href)whereprefixisNonefor the default namespace declaration. The variant in use depends on the build feature flags — callers should treat it as opaque. - Quirks
Mode - HTML5 quirks-mode flag set from the DOCTYPE. Only meaningful for HTML
documents; XML documents always carry
NoneforDocument::html_metadata.