1use std::num::NonZeroU32;
13
14use crate::tokenizer::{Attribute as TokenAttribute, Position};
15
16#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
20pub struct NodeId(NonZeroU32);
21
22impl NodeId {
23 fn from_index(index: usize) -> Self {
24 Self(
25 NonZeroU32::new(u32::try_from(index).expect("node arena index overflowed u32"))
26 .expect("node arena index must be nonzero"),
27 )
28 }
29
30 fn index(self) -> usize {
31 self.0.get() as usize
32 }
33}
34
35#[derive(Debug, Clone, PartialEq, Eq)]
39pub struct Attribute {
40 pub name: String,
41 pub value: String,
42 pub namespace: Option<String>,
43}
44
45impl From<TokenAttribute> for Attribute {
46 fn from(attribute: TokenAttribute) -> Self {
53 Attribute {
54 name: attribute.name,
55 value: attribute.value,
56 namespace: None,
57 }
58 }
59}
60
61#[derive(Debug, Clone, PartialEq, Eq)]
71pub enum NodeKind {
72 Document,
74 Element {
76 name: String,
77 namespace: Option<String>,
78 attributes: Vec<Attribute>,
79 },
80 Text { content: String },
82 Comment { content: String },
84 ProcessingInstruction { target: String, data: String },
91 Doctype {
95 name: Option<String>,
96 public_identifier: Option<String>,
97 system_identifier: Option<String>,
98 },
99 DocumentFragment,
110}
111
112#[derive(Debug, Clone)]
118pub struct Node {
119 pub kind: NodeKind,
120 pub position: Option<Position>,
123 parent: Option<NodeId>,
124 first_child: Option<NodeId>,
125 last_child: Option<NodeId>,
126 next_sibling: Option<NodeId>,
127 prev_sibling: Option<NodeId>,
128}
129
130impl Node {
131 fn new(kind: NodeKind, position: Option<Position>) -> Self {
132 Node {
133 kind,
134 position,
135 parent: None,
136 first_child: None,
137 last_child: None,
138 next_sibling: None,
139 prev_sibling: None,
140 }
141 }
142}
143
144#[derive(Debug)]
155pub struct Document {
156 nodes: Vec<Node>,
157 root: NodeId,
158}
159
160impl Document {
161 pub(crate) fn new() -> Self {
165 let placeholder = Node::new(NodeKind::Document, None);
166 let root_node = Node::new(NodeKind::Document, None);
167 Document {
168 nodes: vec![placeholder, root_node],
169 root: NodeId::from_index(1),
170 }
171 }
172
173 pub fn root(&self) -> NodeId {
175 self.root
176 }
177
178 pub fn node(&self, id: NodeId) -> &Node {
181 &self.nodes[id.index()]
182 }
183
184 pub(crate) fn node_mut(&mut self, id: NodeId) -> &mut Node {
188 &mut self.nodes[id.index()]
189 }
190
191 pub fn parent(&self, id: NodeId) -> Option<NodeId> {
194 self.node(id).parent
195 }
196
197 pub(crate) fn last_child(&self, id: NodeId) -> Option<NodeId> {
198 self.node(id).last_child
199 }
200
201 pub(crate) fn prev_sibling(&self, id: NodeId) -> Option<NodeId> {
202 self.node(id).prev_sibling
203 }
204
205 pub(crate) fn new_node(&mut self, kind: NodeKind, position: Option<Position>) -> NodeId {
208 self.nodes.push(Node::new(kind, position));
209 NodeId::from_index(self.nodes.len() - 1)
210 }
211
212 pub(crate) fn clone_subtree(&mut self, source: NodeId) -> NodeId {
224 let kind = self.node(source).kind.clone();
225 let clone = self.new_node(kind, None);
226 let children: Vec<_> = self.children(source).collect();
227 for child in children {
228 let child_clone = self.clone_subtree(child);
229 self.append_child(clone, child_clone);
230 }
231 clone
232 }
233
234 pub(crate) fn remove(&mut self, node: NodeId) {
247 let Some(parent) = self.node(node).parent else {
248 return;
249 };
250 let previous_sibling = self.node(node).prev_sibling;
251 let next_sibling = self.node(node).next_sibling;
252 match previous_sibling {
253 Some(previous_sibling) => {
254 self.nodes[previous_sibling.index()].next_sibling = next_sibling;
255 }
256 None => self.nodes[parent.index()].first_child = next_sibling,
257 }
258 match next_sibling {
259 Some(next_sibling) => {
260 self.nodes[next_sibling.index()].prev_sibling = previous_sibling;
261 }
262 None => self.nodes[parent.index()].last_child = previous_sibling,
263 }
264 let node = &mut self.nodes[node.index()];
265 node.parent = None;
266 node.prev_sibling = None;
267 node.next_sibling = None;
268 }
269
270 pub(crate) fn is_inclusive_ancestor(&self, ancestor: NodeId, node: NodeId) -> bool {
277 let mut current = Some(node);
278 while let Some(current_node) = current {
279 if current_node == ancestor {
280 return true;
281 }
282 current = self.node(current_node).parent;
283 }
284 false
285 }
286
287 pub(crate) fn insert_before(
304 &mut self,
305 parent: NodeId,
306 reference: Option<NodeId>,
307 new_node: NodeId,
308 ) {
309 self.remove(new_node);
310 match reference {
311 None => {
312 let previous_last_child = self.node(parent).last_child;
313 self.nodes[new_node.index()].parent = Some(parent);
314 self.nodes[new_node.index()].prev_sibling = previous_last_child;
315 if let Some(previous_last_child) = previous_last_child {
316 self.nodes[previous_last_child.index()].next_sibling = Some(new_node);
317 } else {
318 self.nodes[parent.index()].first_child = Some(new_node);
319 }
320 self.nodes[parent.index()].last_child = Some(new_node);
321 }
322 Some(reference) => {
323 debug_assert_eq!(
324 self.node(reference).parent,
325 Some(parent),
326 "insert_before's reference node must already be a child of parent"
327 );
328 let previous_sibling = self.node(reference).prev_sibling;
329 self.nodes[new_node.index()].parent = Some(parent);
330 self.nodes[new_node.index()].next_sibling = Some(reference);
331 self.nodes[new_node.index()].prev_sibling = previous_sibling;
332 self.nodes[reference.index()].prev_sibling = Some(new_node);
333 if let Some(previous_sibling) = previous_sibling {
334 self.nodes[previous_sibling.index()].next_sibling = Some(new_node);
335 } else {
336 self.nodes[parent.index()].first_child = Some(new_node);
337 }
338 }
339 }
340 }
341
342 pub(crate) fn append_child(&mut self, parent: NodeId, child: NodeId) {
345 self.insert_before(parent, None, child);
346 }
347
348 pub fn children(&self, id: NodeId) -> Children<'_> {
351 Children {
352 document: self,
353 next: self.node(id).first_child,
354 }
355 }
356}
357
358impl Default for Document {
359 fn default() -> Self {
360 Self::new()
361 }
362}
363
364pub struct Children<'a> {
367 document: &'a Document,
368 next: Option<NodeId>,
369}
370
371impl Iterator for Children<'_> {
372 type Item = NodeId;
373
374 fn next(&mut self) -> Option<NodeId> {
375 let current = self.next?;
376 self.next = self.document.node(current).next_sibling;
377 Some(current)
378 }
379}
380
381#[cfg(test)]
382mod tests {
383 use super::{Document, NodeKind, Position};
384
385 fn pos(line: u32, column: u32, byte_offset: usize) -> Position {
386 Position {
387 line,
388 column,
389 byte_offset,
390 }
391 }
392
393 #[test]
394 fn new_document_has_only_its_own_document_node() {
395 let document = Document::new();
396 assert_eq!(document.node(document.root()).kind, NodeKind::Document);
397 assert_eq!(document.children(document.root()).count(), 0);
398 assert_eq!(document.node(document.root()).position, None);
399 }
400
401 #[test]
402 fn append_child_attaches_a_detached_node_as_the_last_child() {
403 let mut document = Document::new();
404 let root = document.root();
405 let p = document.new_node(
406 NodeKind::Element {
407 name: "p".to_owned(),
408 namespace: Some("http://www.w3.org/1999/xhtml".to_owned()),
409 attributes: vec![],
410 },
411 Some(pos(1, 1, 0)),
412 );
413 document.append_child(root, p);
414
415 let children: Vec<_> = document.children(root).collect();
416 assert_eq!(children, vec![p]);
417 assert_eq!(document.parent(p), Some(root));
418 }
419
420 #[test]
421 fn multiple_children_are_yielded_in_document_order() {
422 let mut document = Document::new();
423 let root = document.root();
424 let first = document.new_node(
425 NodeKind::Text {
426 content: "a".to_owned(),
427 },
428 None,
429 );
430 let second = document.new_node(
431 NodeKind::Text {
432 content: "b".to_owned(),
433 },
434 None,
435 );
436 let third = document.new_node(
437 NodeKind::Text {
438 content: "c".to_owned(),
439 },
440 None,
441 );
442 document.append_child(root, first);
443 document.append_child(root, second);
444 document.append_child(root, third);
445
446 let children: Vec<_> = document.children(root).collect();
447 assert_eq!(children, vec![first, second, third]);
448 }
449
450 #[test]
451 fn insert_before_a_reference_places_the_new_node_in_the_middle() {
452 let mut document = Document::new();
453 let root = document.root();
454 let first = document.new_node(
455 NodeKind::Text {
456 content: "a".to_owned(),
457 },
458 None,
459 );
460 let third = document.new_node(
461 NodeKind::Text {
462 content: "c".to_owned(),
463 },
464 None,
465 );
466 document.append_child(root, first);
467 document.append_child(root, third);
468 let second = document.new_node(
469 NodeKind::Text {
470 content: "b".to_owned(),
471 },
472 None,
473 );
474 document.insert_before(root, Some(third), second);
475
476 let children: Vec<_> = document.children(root).collect();
477 assert_eq!(children, vec![first, second, third]);
478 }
479
480 #[test]
481 fn insert_before_at_the_start_updates_first_child() {
482 let mut document = Document::new();
483 let root = document.root();
484 let second = document.new_node(
485 NodeKind::Text {
486 content: "b".to_owned(),
487 },
488 None,
489 );
490 document.append_child(root, second);
491 let first = document.new_node(
492 NodeKind::Text {
493 content: "a".to_owned(),
494 },
495 None,
496 );
497 document.insert_before(root, Some(second), first);
498
499 let children: Vec<_> = document.children(root).collect();
500 assert_eq!(children, vec![first, second]);
501 }
502
503 #[test]
504 fn nested_children_are_independent_of_their_parents_siblings() {
505 let mut document = Document::new();
506 let root = document.root();
507 let div = document.new_node(
508 NodeKind::Element {
509 name: "div".to_owned(),
510 namespace: Some("http://www.w3.org/1999/xhtml".to_owned()),
511 attributes: vec![],
512 },
513 Some(pos(1, 1, 0)),
514 );
515 document.append_child(root, div);
516 let text = document.new_node(
517 NodeKind::Text {
518 content: "hi".to_owned(),
519 },
520 Some(pos(1, 6, 5)),
521 );
522 document.append_child(div, text);
523
524 assert_eq!(document.children(root).collect::<Vec<_>>(), vec![div]);
525 assert_eq!(document.children(div).collect::<Vec<_>>(), vec![text]);
526 assert_eq!(document.parent(text), Some(div));
527 }
528
529 #[test]
530 fn synthesized_nodes_carry_no_position_while_parsed_nodes_do() {
531 let mut document = Document::new();
532 let root = document.root();
533 let implied_html = document.new_node(
534 NodeKind::Element {
535 name: "html".to_owned(),
536 namespace: Some("http://www.w3.org/1999/xhtml".to_owned()),
537 attributes: vec![],
538 },
539 None,
540 );
541 document.append_child(root, implied_html);
542 let parsed_p = document.new_node(
543 NodeKind::Element {
544 name: "p".to_owned(),
545 namespace: Some("http://www.w3.org/1999/xhtml".to_owned()),
546 attributes: vec![],
547 },
548 Some(pos(1, 1, 0)),
549 );
550 document.append_child(implied_html, parsed_p);
551
552 assert_eq!(document.node(implied_html).position, None);
553 assert_eq!(document.node(parsed_p).position, Some(pos(1, 1, 0)));
554 }
555
556 #[test]
557 fn remove_detaches_a_node_and_relinks_its_siblings() {
558 let mut document = Document::new();
559 let root = document.root();
560 let first = document.new_node(
561 NodeKind::Text {
562 content: "a".to_owned(),
563 },
564 None,
565 );
566 let second = document.new_node(
567 NodeKind::Text {
568 content: "b".to_owned(),
569 },
570 None,
571 );
572 let third = document.new_node(
573 NodeKind::Text {
574 content: "c".to_owned(),
575 },
576 None,
577 );
578 document.append_child(root, first);
579 document.append_child(root, second);
580 document.append_child(root, third);
581
582 document.remove(second);
583
584 assert_eq!(
585 document.children(root).collect::<Vec<_>>(),
586 vec![first, third]
587 );
588 assert_eq!(document.parent(second), None);
589 }
590
591 #[test]
592 fn remove_on_a_node_with_no_parent_is_a_no_op() {
593 let mut document = Document::new();
594 let detached = document.new_node(
595 NodeKind::Text {
596 content: "a".to_owned(),
597 },
598 None,
599 );
600 document.remove(detached);
601 assert_eq!(document.parent(detached), None);
602 }
603
604 #[test]
605 fn insert_before_an_already_attached_node_moves_it() {
606 let mut document = Document::new();
613 let root = document.root();
614 let old_parent = document.new_node(
615 NodeKind::Element {
616 name: "div".to_owned(),
617 namespace: Some("http://www.w3.org/1999/xhtml".to_owned()),
618 attributes: vec![],
619 },
620 None,
621 );
622 let new_parent = document.new_node(
623 NodeKind::Element {
624 name: "span".to_owned(),
625 namespace: Some("http://www.w3.org/1999/xhtml".to_owned()),
626 attributes: vec![],
627 },
628 None,
629 );
630 document.append_child(root, old_parent);
631 document.append_child(root, new_parent);
632 let child = document.new_node(
633 NodeKind::Text {
634 content: "hi".to_owned(),
635 },
636 None,
637 );
638 document.append_child(old_parent, child);
639
640 document.append_child(new_parent, child);
641
642 assert_eq!(document.children(old_parent).count(), 0);
643 assert_eq!(
644 document.children(new_parent).collect::<Vec<_>>(),
645 vec![child]
646 );
647 assert_eq!(document.parent(child), Some(new_parent));
648 }
649
650 #[test]
651 fn is_inclusive_ancestor_covers_self_and_real_ancestors_but_not_others() {
652 let mut document = Document::new();
653 let root = document.root();
654 let div = document.new_node(
655 NodeKind::Element {
656 name: "div".to_owned(),
657 namespace: Some("http://www.w3.org/1999/xhtml".to_owned()),
658 attributes: vec![],
659 },
660 None,
661 );
662 document.append_child(root, div);
663 let span = document.new_node(
664 NodeKind::Element {
665 name: "span".to_owned(),
666 namespace: Some("http://www.w3.org/1999/xhtml".to_owned()),
667 attributes: vec![],
668 },
669 None,
670 );
671 document.append_child(div, span);
672 let unrelated = document.new_node(
673 NodeKind::Text {
674 content: "x".to_owned(),
675 },
676 None,
677 );
678 document.append_child(root, unrelated);
679
680 assert!(document.is_inclusive_ancestor(span, span));
681 assert!(document.is_inclusive_ancestor(div, span));
682 assert!(document.is_inclusive_ancestor(root, span));
683 assert!(!document.is_inclusive_ancestor(unrelated, span));
684 assert!(!document.is_inclusive_ancestor(span, div));
685 }
686
687 #[test]
688 fn clone_subtree_deep_copies_kind_and_structure_into_new_nodes() {
689 let mut document = Document::new();
690 let root = document.root();
691 let original = document.new_node(
692 NodeKind::Element {
693 name: "b".to_owned(),
694 namespace: Some("http://www.w3.org/1999/xhtml".to_owned()),
695 attributes: vec![],
696 },
697 Some(pos(1, 1, 0)),
698 );
699 document.append_child(root, original);
700 let text = document.new_node(
701 NodeKind::Text {
702 content: "hi".to_owned(),
703 },
704 Some(pos(1, 4, 3)),
705 );
706 document.append_child(original, text);
707
708 let clone = document.clone_subtree(original);
709
710 assert_ne!(clone, original);
711 assert_eq!(document.node(clone).kind, document.node(original).kind);
712 assert_eq!(document.parent(clone), None);
714 let clone_children: Vec<_> = document.children(clone).collect();
715 assert_eq!(clone_children.len(), 1);
716 assert_ne!(clone_children[0], text);
717 assert_eq!(
718 document.node(clone_children[0]).kind,
719 NodeKind::Text {
720 content: "hi".to_owned()
721 }
722 );
723 assert_eq!(document.node(clone).position, None);
725 assert_eq!(document.children(original).collect::<Vec<_>>(), vec![text]);
727 }
728}