use regex::Regex;
mod parse;
pub use parse::parse;
#[derive(Debug, PartialEq)]
pub struct PatternMatch {
pub patterns: Vec<Pattern>,
}
#[derive(Debug)]
pub enum Pattern {
Regex(Box<Regex>),
String(String, bool),
Identifier(String),
}
#[derive(Debug)]
pub enum Match {
Begin,
End,
Index(i64),
Regex(Box<Regex>),
}
#[derive(Debug, PartialEq)]
pub struct Range(pub Match, pub Match);
#[derive(Debug, PartialEq)]
pub enum Selector {
Match(Match),
Range(Range),
Pattern(PatternMatch),
Negate(Box<Selector>),
Conjunction(Box<Selector>, Box<Selector>),
Disjunction(Box<Selector>, Box<Selector>),
}
#[derive(Debug, PartialEq)]
pub enum Expression {
String(String, bool),
Identifier(String),
}
#[derive(Debug)]
pub enum Statement {
Print(Expression),
Quit,
Subst(Box<Regex>, Expression),
Gsubst(Box<Regex>, Expression),
Read(Expression),
Write(Expression),
Exec(Expression),
Append(Expression),
Set(Expression),
#[cfg(feature = "bind")]
Bind(String),
}
#[derive(Debug, PartialEq)]
pub enum Body {
Bare(Statement),
Single(Selector, Statement),
Guard(Selector, Seq),
}
#[derive(Debug, PartialEq)]
pub struct Seq {
pub subnodes: Vec<Body>,
pub(crate) toplevel: bool,
}
impl PartialEq for Match {
fn eq(&self, other: &Match) -> bool {
match (self, other) {
(Match::Index(a), Match::Index(b)) => a == b,
(Match::Regex(a), Match::Regex(b)) => a.to_string() == b.to_string(),
(Match::Begin, Match::Begin) => true,
(Match::End, Match::End) => true,
_ => false,
}
}
}
impl PartialEq for Pattern {
fn eq(&self, other: &Pattern) -> bool {
match (self, other) {
(Pattern::Regex(a), Pattern::Regex(b)) => a.to_string() == b.to_string(),
(Pattern::String(ss, si), Pattern::String(os, oi)) => ss == os && si == oi,
(Pattern::Identifier(a), Pattern::Identifier(b)) => a == b,
_ => false,
}
}
}
impl PartialEq for Statement {
fn eq(&self, other: &Statement) -> bool {
match (self, other) {
(Statement::Quit, Statement::Quit) => true,
(Statement::Print(se), Statement::Print(oe)) => se == oe,
(Statement::Subst(sr, se), Statement::Subst(or, oe)) => {
sr.to_string() == or.to_string() && se == oe
}
(Statement::Gsubst(sr, se), Statement::Gsubst(or, oe)) => {
sr.to_string() == or.to_string() && se == oe
}
(Statement::Read(se), Statement::Read(oe)) => se == oe,
(Statement::Write(se), Statement::Write(oe)) => se == oe,
(Statement::Exec(se), Statement::Exec(oe)) => se == oe,
(Statement::Append(se), Statement::Append(oe)) => se == oe,
(Statement::Set(se), Statement::Set(oe)) => se == oe,
_ => false,
}
}
}