web_parser/parser/
node.rs

1use crate::prelude::*;
2use super::Nodes;
3
4/// The HTML node
5#[derive(Debug, Clone)]
6pub struct Node<'a> {
7    element: scraper::ElementRef<'a>,
8    selector: scraper::Selector
9}
10
11impl<'a> Node<'a> {
12    /// Creates a new Node from scraper::ElementRef
13    pub(crate) fn new(element: scraper::ElementRef<'a>) -> Self {
14        Self {
15            element,
16            selector: scraper::Selector::parse("*").unwrap()
17        }
18    }
19
20    /// Select HTML node by CSS selector
21    pub fn select(&self, selector: &'static str) -> Result<Option<Node<'a>>> {
22        let sel = scraper::Selector::parse(selector)?;
23        
24        let node = self.element
25            .select(&sel)
26            .next()
27            .map(Node::new);
28        
29        Ok(node)
30    }
31
32    /// Select HTML nodes by CSS selector
33    pub fn select_all(&mut self, selector: &'static str) -> Result<Option<Nodes>> {
34        self.selector = scraper::Selector::parse(selector)?;
35        let mut nodes = self.element.select(&self.selector).peekable();
36
37        if nodes.peek().is_some() {
38            Ok(Some(Nodes::new(None, Some(nodes))))
39        } else {
40            Ok(None)
41        }
42    }
43
44    /// Returns a node parent
45    pub fn parent(&self) -> Option<Node<'a>> {
46        self.element.parent()
47            .and_then(|node| scraper::ElementRef::wrap(node))
48            .map(Node::new)
49    }
50
51    /// Returns a node attribute
52    pub fn attr(&self, name: &str) -> Option<&str> {
53        self.element.value().attr(name)
54    }
55
56    /// Returns a node text contents
57    pub fn text(&self) -> String {
58        self.element.text().collect()
59    }
60
61    /// Returns a node inner HTML
62    pub fn html(&self) -> String {
63        self.element.html()
64    }
65}