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 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61
mod item; pub use item::Item; mod error; pub use error::PatternError; /// Pattern that is used for matching. /// /// Consists of multiple `finder::Item` elements /// /// For example the following pattern: /// /// ```text /// Pattern::new("args -> arglist -> 2 -> default") /// ``` /// /// can find a node that represents constant `FIND_ME` in the following code: /// /// ```text /// def foo(a, b, c = FIND_ME) /// end /// ``` /// /// It means: /// 1. enter `.args` of the `Def` node (`(a, b, c = FIND_ME`)) /// 2. enter its `.argslist` (`a, b, c = FIND_ME`) /// 3. enter element `[2]` (`c = FIND_ME`) /// 4. enter `.default` of the `Optarg` node (`FIND_ME`) #[derive(Debug, PartialEq, Eq)] pub struct Pattern { parts: Vec<Item>, } impl Pattern { /// Constructs a pattern from a string, returns an error on the first sub-pattern error pub fn new(input: &str) -> Result<Self, PatternError> { let mut parts: Vec<Item> = vec![]; for part in input.split(" -> ") { let part = Item::new(part)?; parts.push(part); } Ok(Self { parts }) } /// Returns `true` if pattern is empty pub fn empty() -> Self { Self { parts: vec![] } } /// Pushes a new `Item` into a pattern pub fn push(&mut self, item: Item) { self.parts.push(item) } /// Pops an `Item` from a pattern pub fn pop(&mut self) -> Option<Item> { self.parts.pop() } }