use std::fmt::Display;
#[derive(Debug, PartialEq)]
pub struct Program {
pub expressions: Vec<Expression>,
}
#[derive(Debug, PartialEq)]
pub enum Expression {
Literal(Literal),
BackReference(BackReference),
AnchorAssertion(AnchorAssertionName),
BoundaryAssertion(BoundaryAssertionName),
Group(Vec<Expression>),
FunctionCall(Box<FunctionCall>),
Or(Box<Expression>, Box<Expression>),
}
#[derive(Debug, PartialEq)]
pub struct FunctionCall {
pub name: FunctionName,
pub args: Vec<FunctionCallArg>,
}
#[derive(Debug, PartialEq)]
pub enum FunctionCallArg {
Number(usize),
Identifier(String),
Expression(Box<Expression>),
}
#[derive(Debug, PartialEq)]
pub enum Literal {
Char(char),
String(String),
Special(SpecialCharName),
CharSet(CharSet),
PresetCharSet(PresetCharSetName),
}
#[derive(Debug, PartialEq)]
pub struct CharSet {
pub negative: bool,
pub elements: Vec<CharSetElement>,
}
#[derive(Debug, PartialEq)]
pub enum CharSetElement {
Char(char),
CharRange(CharRange),
PresetCharSet(PresetCharSetName), CharSet(Box<CharSet>), }
#[derive(Debug, PartialEq)]
pub struct CharRange {
pub start: char,
pub end_included: char,
}
#[derive(Debug, PartialEq)]
pub enum BackReference {
Index(usize),
Name(String),
}
impl Display for BackReference {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
BackReference::Index(index) => write!(f, "^{}", index),
BackReference::Name(name) => f.write_str(name),
}
}
}
#[derive(Debug, PartialEq, Clone, Copy)]
pub enum AnchorAssertionName {
Start,
End,
}
#[derive(Debug, PartialEq, Clone, Copy)]
pub enum BoundaryAssertionName {
IsBound,
IsNotBound,
}
impl Display for AnchorAssertionName {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let name_str = match self {
AnchorAssertionName::Start => "start",
AnchorAssertionName::End => "end",
};
f.write_str(name_str)
}
}
impl Display for BoundaryAssertionName {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let name_str = match self {
BoundaryAssertionName::IsBound => "is_bound",
BoundaryAssertionName::IsNotBound => "is_not_bound",
};
f.write_str(name_str)
}
}
#[allow(clippy::enum_variant_names)]
#[derive(Debug, PartialEq, Clone, Copy)]
pub enum PresetCharSetName {
CharWord,
CharNotWord,
CharDigit,
CharNotDigit,
CharSpace,
CharNotSpace,
}
impl Display for PresetCharSetName {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let name_str = match self {
PresetCharSetName::CharWord => "char_word",
PresetCharSetName::CharNotWord => "char_not_word",
PresetCharSetName::CharDigit => "char_digit",
PresetCharSetName::CharNotDigit => "char_not_digit",
PresetCharSetName::CharSpace => "char_space",
PresetCharSetName::CharNotSpace => "char_not_space",
};
f.write_str(name_str)
}
}
#[derive(Debug, PartialEq, Clone, Copy)]
pub enum SpecialCharName {
CharAny,
}
impl Display for SpecialCharName {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
SpecialCharName::CharAny => f.write_str("char_any"),
}
}
}
#[derive(Debug, PartialEq, Clone, Copy)]
pub enum FunctionName {
Optional,
OneOrMore,
ZeroOrMore,
Repeat,
RepeatRange,
AtLeast,
OptionalLazy,
OneOrMoreLazy,
ZeroOrMoreLazy,
RepeatRangeLazy,
AtLeastLazy,
IsBefore, IsAfter, IsNotBefore, IsNotAfter,
Name,
Index,
}