1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
mod pattern;
pub use pattern::{Item as PatternItem, Pattern, PatternError};

use crate::traverse::visitor::Visitor;
use crate::Node;

/// A struct to find sub-nodes in AST by by a given `Pattern`
#[derive(Debug)]
pub struct Finder {
    pattern: Pattern,
    result: Option<Node>,
}

mod finder_gen;

impl Finder {
    /// Performs a search of a given pattern on a given AST.
    ///
    /// `pattern` is a string slice that is used to construct a `Pattern`.
    pub fn run(pattern: &str, root: &Node) -> Result<Option<Node>, PatternError> {
        let mut pattern = Pattern::new(pattern)?;
        if pattern.parts.first() == Some(&PatternItem::Root) {
            pattern.unshift();
        }
        let mut finder = Self {
            pattern,
            result: None,
        };
        finder.visit(root);
        Ok(finder.result)
    }
}

#[cfg(test)]
mod tests;