A Send/Sync-friendly fork of markup5ever_rcdom on the spider-rs atomic-tendril stack.
Upstream markup5ever_rcdom 0.40 produces an Rc<Node> DOM that is !Send, both because of Rc itself and because it stores StrTendril (which is !Send in upstream tendril). That blocks any future holding the parsed DOM from being Send-able for tokio::spawn on a multi-threaded runtime.
This fork makes three changes:
-
Uses the spider-* fork stack:
spider-tendril(atomic refcount default),spider-markup5ever,spider-html5ever. The Atomic-tendril propagation is automatic, with no source code changes needed for the tendril side. -
Adds
unsafe impl Send + Sync for Nodewith a documented soundness invariant: aNodeis owned by exactly one task at a time. The future may move between tokio worker threads (work-stealing), but only one thread polls it at any instant, so no two threads ever access the sameNodesimultaneously. Cloning aHandleand using one clone on another thread while the original is still live on the source thread is undefined behavior. Do not do that. -
Uses
Arcand its matchingWeakfor node handles. Earlier fork versions still importedstd::rc::Rc, despite the invariant comment describingArc; 0.40.0 corrects that mismatch soHandleandRcDomsatisfySend. Code explicitly usingstd::rc::Rcwith these handles must usestd::sync::Arcinstead.
Arc<Node>: Send requires Node: Send + Sync. With the unsafe impl, this holds, and the entire DOM can move between threads as a unit.
[dependencies]
spider-markup5ever_rcdom = "0.40"use markup5ever_rcdom::{Handle, NodeData, RcDom, SerializableHandle};The library still imports as markup5ever_rcdom, so the dependency line in Cargo.toml is usually the only change. The exception is handle types: see the Arc note above if your code names std::rc::Rc directly. Pair with spider-html5ever and spider-markup5ever for the full Send-able parser-and-DOM stack.
This crate is built for the express purpose of writing automated tests for the html5ever and xml5ever crates. It is not intended to be a production-quality DOM implementation, and has not been fuzzed or tested against arbitrary, malicious, or nontrivial inputs. No maintenance or support for any such issues will be provided. If you use this DOM implementation in a production, user-facing system, you do so at your own risk.
Licensed under either of Apache License, Version 2.0 or MIT license at your option, matching the upstream markup5ever_rcdom license.
Vendored from servo/html5ever a193ea7f2492d1e51eb32955a09c241345348dba (0.40.0-dev). Requires Rust 1.85. UPSTREAM.toml records the source directory and fork delta.
Run scripts/check-drift.sh to list upstream commits since the pin. Run scripts/sync-upstream.sh --to <ref> from a clean tree to apply source changes and advance the pin. The sync preserves Cargo.toml, README.md, and the recorded exclusions; review dependencies and fork invariants before committing.