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 errors: Vec<String>,
16}
17
18impl Document {
19 pub const fn new(children: Vec<Arc<Node>>) -> Self {
21 Self {
22 children,
23 errors: vec![],
24 }
25 }
26
27 pub fn children(&self) -> impl Iterator<Item = &Node> {
29 self.children.iter().map(Deref::deref)
30 }
31
32 pub fn errors(&self) -> impl Iterator<Item = &str> {
34 self.errors.iter().map(String::as_str)
35 }
36
37 pub fn set_errors(mut self, errors: Vec<String>) -> Self {
39 self.errors = errors;
40 self
41 }
42
43 pub fn base(&self) -> Option<&str> {
45 self.children()
46 .find_map(|node| Self::find_base(node))
47 .and_then(|element| {
48 element
49 .attributes()
50 .find(|(key, _)| *key == "href")
51 .map(|(_, value)| value)
52 })
53 }
54
55 fn find_base(node: &Node) -> Option<&Element> {
56 match node {
57 Node::Element(element) if element.name() == "base" => Some(element),
58 Node::Element(element) => element.children().find_map(|node| Self::find_base(node)),
59 _ => None,
60 }
61 }
62
63 pub(crate) fn from_markup5ever(node: &markup5ever_rcdom::Node) -> Self {
64 debug_assert!(matches!(node.data, NodeData::Document));
65
66 Self::new(
67 node.children
68 .borrow()
69 .iter()
70 .flat_map(|node| Node::from_markup5ever(node))
71 .map(Arc::new)
72 .collect(),
73 )
74 }
75}