use crate::bytes::Payload;
use crate::inspect::{PayloadView, RuleActionView, RuleAnchor, RulePosition, RuleRepeat};
use crate::source::SourceLineNumber;
#[derive(Debug, PartialEq, Eq)]
pub(crate) enum RuleAction {
Rewrite(RewriteAction),
Return(Payload),
}
impl RuleAction {
pub(crate) fn view(&self) -> RuleActionView<'_> {
match self {
Self::Rewrite(action) => action.view(),
Self::Return(payload) => RuleActionView::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) -> RuleActionView<'_> {
match self {
Self::Replace(payload) => RuleActionView::Replace(PayloadView::new(payload)),
Self::MoveStart(payload) => RuleActionView::MoveStart(PayloadView::new(payload)),
Self::MoveEnd(payload) => RuleActionView::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: RuleAction,
}
impl RuleBody {
pub(crate) const fn new(action: RuleAction) -> 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, Default)]
pub(crate) struct OnceRuleCount {
value: usize,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub(crate) struct OnceRuleSlot {
zero_based: usize,
}
impl OnceRuleCount {
pub(crate) const fn new(value: usize) -> Self {
Self { value }
}
pub(crate) const fn get(self) -> usize {
self.value
}
pub(crate) fn checked_next(self) -> Option<Self> {
let next = self.value.checked_add(1)?;
Some(Self { value: next })
}
pub(crate) fn assign_next_slot(self) -> Option<(OnceRuleSlot, Self)> {
let next_count = self.checked_next()?;
Some((
OnceRuleSlot {
zero_based: self.value,
},
next_count,
))
}
}
impl OnceRuleSlot {
pub(crate) const fn get(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,
}
}
pub(crate) const fn is_once(self) -> bool {
match self {
Self::Always => false,
Self::Once(_) => true,
}
}
}
#[derive(Debug, PartialEq, Eq)]
pub(crate) struct Rule {
position: RulePosition,
line_number: SourceLineNumber,
availability: RuleAvailability,
anchor: RuleAnchorSyntax,
lhs: Payload,
action: RuleAction,
}
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) -> &RuleAction {
&self.action
}
}