use crate::bytes::Payload;
use crate::inspect::{
OnceRuleCount, PayloadView, RuleAction, RuleAnchor, RulePosition, RuleRepeat,
};
use crate::source::SourceLineNumber;
#[derive(Debug, PartialEq, Eq)]
pub(crate) enum ParsedRuleAction {
Rewrite(RewriteAction),
Return(Payload),
}
impl ParsedRuleAction {
pub(crate) fn view(&self) -> RuleAction<PayloadView<'_>> {
match self {
Self::Rewrite(action) => action.view(),
Self::Return(payload) => RuleAction::Return(PayloadView::new(payload)),
}
}
pub(crate) const fn canonical_right_side(&self) -> CanonicalRightSide<'_> {
match self {
Self::Rewrite(action) => action.canonical_right_side(),
Self::Return(payload) => CanonicalRightSide::Return(payload),
}
}
}
#[derive(Debug, PartialEq, Eq)]
pub(crate) enum RewriteAction {
Replace(Payload),
MoveStart(Payload),
MoveEnd(Payload),
}
impl RewriteAction {
pub(crate) fn view(&self) -> RuleAction<PayloadView<'_>> {
match self {
Self::Replace(payload) => RuleAction::Replace(PayloadView::new(payload)),
Self::MoveStart(payload) => RuleAction::MoveStart(PayloadView::new(payload)),
Self::MoveEnd(payload) => RuleAction::MoveEnd(PayloadView::new(payload)),
}
}
pub(crate) const fn canonical_right_side(&self) -> CanonicalRightSide<'_> {
match self {
Self::Replace(payload) => CanonicalRightSide::Replace(payload),
Self::MoveStart(payload) => CanonicalRightSide::MoveStart(payload),
Self::MoveEnd(payload) => CanonicalRightSide::MoveEnd(payload),
}
}
pub(crate) const fn payload(&self) -> &Payload {
match self {
Self::Replace(payload) | Self::MoveStart(payload) | Self::MoveEnd(payload) => payload,
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub(crate) enum CanonicalRightSide<'rule> {
Replace(&'rule Payload),
MoveStart(&'rule Payload),
MoveEnd(&'rule Payload),
Return(&'rule Payload),
}
#[derive(Debug, PartialEq, Eq)]
pub(crate) struct RuleHead {
repeat: RuleRepeatSyntax,
anchor: RuleAnchorSyntax,
lhs: Payload,
}
impl RuleHead {
pub(crate) fn new(repeat: RuleRepeatSyntax, anchor: RuleAnchorSyntax, lhs: Payload) -> Self {
Self {
repeat,
anchor,
lhs,
}
}
}
#[derive(Debug, PartialEq, Eq)]
pub(crate) struct RuleBody {
action: ParsedRuleAction,
}
impl RuleBody {
pub(crate) const fn new(action: ParsedRuleAction) -> Self {
Self { action }
}
}
#[derive(Debug, PartialEq, Eq)]
pub(crate) struct ParsedRule {
line_number: SourceLineNumber,
head: RuleHead,
body: RuleBody,
}
impl ParsedRule {
pub(crate) const fn from_parts(
line_number: SourceLineNumber,
head: RuleHead,
body: RuleBody,
) -> Self {
Self {
line_number,
head,
body,
}
}
pub(crate) const fn line_number(&self) -> SourceLineNumber {
self.line_number
}
pub(crate) const fn repeat_syntax(&self) -> RuleRepeatSyntax {
self.head.repeat
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub(crate) enum RuleRepeatSyntax {
Always,
Once,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub(crate) enum RuleAnchorSyntax {
Anywhere,
Start,
End,
}
impl RuleAnchorSyntax {
pub(crate) const fn public_anchor(self) -> RuleAnchor {
match self {
Self::Anywhere => RuleAnchor::Anywhere,
Self::Start => RuleAnchor::Start,
Self::End => RuleAnchor::End,
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub(crate) struct OnceRuleSlot {
zero_based: usize,
}
impl OnceRuleSlot {
pub(crate) const fn from_count(count: OnceRuleCount) -> Self {
Self {
zero_based: count.get(),
}
}
pub(crate) const fn index(self) -> usize {
self.zero_based
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub(crate) enum RuleAvailability {
Always,
Once(OnceRuleSlot),
}
impl RuleAvailability {
pub(crate) const fn public_repeat(self) -> RuleRepeat {
match self {
Self::Always => RuleRepeat::Always,
Self::Once(_) => RuleRepeat::Once,
}
}
}
#[derive(Debug, PartialEq, Eq)]
pub(crate) struct Rule {
position: RulePosition,
line_number: SourceLineNumber,
availability: RuleAvailability,
anchor: RuleAnchorSyntax,
lhs: Payload,
action: ParsedRuleAction,
}
impl Rule {
pub(crate) fn from_parsed(
position: RulePosition,
parsed: ParsedRule,
availability: RuleAvailability,
) -> Self {
Self {
position,
line_number: parsed.line_number,
availability,
anchor: parsed.head.anchor,
lhs: parsed.head.lhs,
action: parsed.body.action,
}
}
pub(crate) const fn position(&self) -> RulePosition {
self.position
}
pub(crate) const fn line_number(&self) -> SourceLineNumber {
self.line_number
}
pub(crate) const fn repeat(&self) -> RuleRepeat {
self.availability.public_repeat()
}
pub(crate) const fn availability(&self) -> RuleAvailability {
self.availability
}
pub(crate) const fn anchor(&self) -> RuleAnchorSyntax {
self.anchor
}
pub(crate) const fn lhs(&self) -> &Payload {
&self.lhs
}
pub(crate) const fn action(&self) -> &ParsedRuleAction {
&self.action
}
}