mod and_pattern;
mod any_pattern;
mod capture_pattern;
mod not_pattern;
mod or_pattern;
mod repeat_pattern;
mod search_pattern;
mod traverse_pattern;
use std::collections::HashMap;
pub(crate) use and_pattern::AndPattern;
pub(crate) use any_pattern::AnyPattern;
use bc_envelope::prelude::*;
pub(crate) use capture_pattern::CapturePattern;
pub(crate) use not_pattern::NotPattern;
pub(crate) use or_pattern::OrPattern;
pub(crate) use repeat_pattern::GroupPattern;
pub(crate) use search_pattern::SearchPattern;
pub(crate) use traverse_pattern::TraversePattern;
use crate::{
Pattern,
pattern::{Matcher, Path, vm::Instr},
};
#[derive(Debug, Clone, Hash, PartialEq, Eq)]
pub enum MetaPattern {
Any(AnyPattern),
And(AndPattern),
Or(OrPattern),
Not(NotPattern),
Search(SearchPattern),
Traverse(TraversePattern),
Group(GroupPattern),
Capture(CapturePattern),
}
impl Matcher for MetaPattern {
fn paths_with_captures(
&self,
haystack: &Envelope,
) -> (Vec<Path>, HashMap<String, Vec<Path>>) {
match self {
MetaPattern::Any(pattern) => pattern.paths_with_captures(haystack),
MetaPattern::And(pattern) => pattern.paths_with_captures(haystack),
MetaPattern::Or(pattern) => pattern.paths_with_captures(haystack),
MetaPattern::Not(pattern) => pattern.paths_with_captures(haystack),
MetaPattern::Search(pattern) => {
pattern.paths_with_captures(haystack)
}
MetaPattern::Traverse(pattern) => {
pattern.paths_with_captures(haystack)
}
MetaPattern::Group(pattern) => {
pattern.paths_with_captures(haystack)
}
MetaPattern::Capture(pattern) => {
pattern.paths_with_captures(haystack)
}
}
}
fn compile(
&self,
code: &mut Vec<Instr>,
lits: &mut Vec<Pattern>,
captures: &mut Vec<String>,
) {
match self {
MetaPattern::Any(pattern) => pattern.compile(code, lits, captures),
MetaPattern::And(pattern) => pattern.compile(code, lits, captures),
MetaPattern::Or(pattern) => pattern.compile(code, lits, captures),
MetaPattern::Not(pattern) => pattern.compile(code, lits, captures),
MetaPattern::Search(pattern) => {
pattern.compile(code, lits, captures)
}
MetaPattern::Traverse(pattern) => {
pattern.compile(code, lits, captures)
}
MetaPattern::Group(pattern) => {
pattern.compile(code, lits, captures)
}
MetaPattern::Capture(pattern) => {
pattern.compile(code, lits, captures)
}
}
}
fn is_complex(&self) -> bool {
match self {
MetaPattern::Any(pattern) => pattern.is_complex(),
MetaPattern::And(pattern) => pattern.is_complex(),
MetaPattern::Or(pattern) => pattern.is_complex(),
MetaPattern::Not(pattern) => pattern.is_complex(),
MetaPattern::Search(pattern) => pattern.is_complex(),
MetaPattern::Traverse(pattern) => pattern.is_complex(),
MetaPattern::Group(pattern) => pattern.is_complex(),
MetaPattern::Capture(pattern) => pattern.is_complex(),
}
}
}
impl std::fmt::Display for MetaPattern {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
MetaPattern::Any(pattern) => write!(f, "{}", pattern),
MetaPattern::And(pattern) => write!(f, "{}", pattern),
MetaPattern::Or(pattern) => write!(f, "{}", pattern),
MetaPattern::Not(pattern) => write!(f, "{}", pattern),
MetaPattern::Search(pattern) => write!(f, "{}", pattern),
MetaPattern::Traverse(pattern) => write!(f, "{}", pattern),
MetaPattern::Group(pattern) => write!(f, "{}", pattern),
MetaPattern::Capture(pattern) => write!(f, "{}", pattern),
}
}
}
impl MetaPattern {
pub(crate) fn collect_capture_names(&self, out: &mut Vec<String>) {
match self {
MetaPattern::Any(_) => {}
MetaPattern::And(p) => {
for pat in p.patterns() {
pat.collect_capture_names(out);
}
}
MetaPattern::Or(p) => {
for pat in p.patterns() {
pat.collect_capture_names(out);
}
}
MetaPattern::Not(p) => p.pattern().collect_capture_names(out),
MetaPattern::Search(p) => p.pattern().collect_capture_names(out),
MetaPattern::Traverse(p) => {
for pat in p.patterns() {
pat.collect_capture_names(out);
}
}
MetaPattern::Group(p) => p.pattern().collect_capture_names(out),
MetaPattern::Capture(p) => {
if !out.contains(&p.name().to_string()) {
out.push(p.name().to_string());
}
p.pattern().collect_capture_names(out);
}
}
}
}