muffy_document/
document.rs1mod element;
4mod node;
5
6pub use self::{element::*, node::*};
7use alloc::sync::Arc;
8use core::ops::Deref;
9use markup5ever_rcdom::NodeData;
10
11#[derive(Debug, Eq, PartialEq)]
13pub struct Document {
14 children: Vec<Arc<Node>>,
15}
16
17impl Document {
18 pub const fn new(children: Vec<Arc<Node>>) -> Self {
20 Self { children }
21 }
22
23 pub fn children(&self) -> impl Iterator<Item = &Node> {
25 self.children.iter().map(Deref::deref)
26 }
27
28 pub fn base(&self) -> Option<&str> {
30 self.children()
31 .find_map(|node| Self::find_base(node))
32 .and_then(|element| {
33 element
34 .attributes()
35 .find(|(key, _)| *key == "href")
36 .map(|(_, value)| value)
37 })
38 }
39
40 fn find_base(node: &Node) -> Option<&Element> {
41 match node {
42 Node::Element(element) if element.name() == "base" => Some(element),
43 Node::Element(element) => element.children().find_map(|node| Self::find_base(node)),
44 _ => None,
45 }
46 }
47
48 pub(crate) fn from_markup5ever(node: &markup5ever_rcdom::Node) -> Self {
49 if matches!(node.data, NodeData::Document) {
50 Self::new(
51 node.children
52 .borrow()
53 .iter()
54 .flat_map(|node| Node::from_markup5ever(node))
55 .map(Arc::new)
56 .collect(),
57 )
58 } else {
59 unreachable!()
60 }
61 }
62}