use crate::tree::{DomTree, NodeData, NodeId}; // A unit of pending serialization work. Held on an explicit heap stack instead // of the call stack so a deeply nested tree cannot overflow the thread stack and // abort the process (a stack overflow is a hard abort that `op_dom`'s // catch_unwind cannot recover). `descendants()` is iterative + capped for the // same reason; the serializer must be too. enum SerializeWork { // Serialize this node; `include_self` mirrors the old recursive param. Node(NodeId, bool), // Emit a previously-opened element's closing tag, after its children. CloseTag(String), } impl DomTree { pub fn outer_html(&self, node_id: NodeId) -> String { let mut buf = String::new(); self.serialize_worklist(vec![SerializeWork::Node(node_id, true)], &mut buf); buf } pub fn inner_html(&self, node_id: NodeId) -> String { let mut buf = String::new(); self.serialize_worklist(self.child_work(self.content_source(node_id)), &mut buf); buf } // The node whose children represent `node_id`'s markup. For a