use std::rc::Rc;
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub(crate) enum GroupBehavior {
Normal,
Ignore,
Lookahead,
NegativeLookahead,
Lookbehind,
NegativeLookbehind,
}
impl GroupBehavior {
pub(crate) fn is_lookaround(self) -> bool {
!matches!(self, GroupBehavior::Normal | GroupBehavior::Ignore)
}
pub(crate) fn is_negative(self) -> bool {
matches!(
self,
GroupBehavior::NegativeLookahead | GroupBehavior::NegativeLookbehind
)
}
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub(crate) enum AnchorKind {
Start,
End,
Boundary,
NotBoundary,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub(crate) enum ClassEscape {
D,
DUpper,
W,
WUpper,
S,
SUpper,
}
#[derive(Debug)]
pub(crate) struct Node {
pub(crate) id: usize,
pub(crate) range: (usize, usize),
pub(crate) raw: String,
pub(crate) kind: NodeKind,
}
pub(crate) type RcNode = Rc<Node>;
#[derive(Debug)]
pub(crate) enum NodeKind {
Alternative { body: Vec<RcNode> },
Disjunction { body: Vec<RcNode> },
Group {
behavior: GroupBehavior,
body: Vec<RcNode>,
},
Quantifier {
min: u64,
max: Option<u64>,
greedy: bool,
symbol: Option<char>,
body: RcNode,
},
Value { code_point: u32 },
CharacterClass { negative: bool, body: Vec<RcNode> },
CharacterClassRange { min: RcNode, max: RcNode },
CharacterClassEscape { value: ClassEscape },
UnicodePropertyEscape { negative: bool, value: String },
Dot,
Anchor { kind: AnchorKind },
Reference { match_index: u64 },
}
impl Node {
pub(crate) fn code_point(&self) -> Option<u32> {
match &self.kind {
NodeKind::Value { code_point } => Some(*code_point),
_ => None,
}
}
}