use core::fmt::Debug;
use core::marker::PhantomData;
use crate::ctor::Ctor;
use crate::ctor::Handler;
use crate::ctx::Match;
use crate::debug_ctor_beg;
use crate::debug_ctor_reval;
use crate::debug_ctor_stage;
use crate::debug_regex_beg;
use crate::debug_regex_reval;
use crate::debug_regex_stage;
use crate::err::Error;
use crate::regex::Regex;
use crate::regex::impl_not_for_regex;
use crate::span::Span;
pub struct Or<C, L, R> {
left: L,
right: R,
marker: PhantomData<C>,
}
impl_not_for_regex!(Or<C, L, R>);
impl<C, L, R> Debug for Or<C, L, R>
where
L: Debug,
R: Debug,
{
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
f.debug_struct("Or")
.field("left", &self.left)
.field("right", &self.right)
.finish()
}
}
impl<C, L, R> Default for Or<C, L, R>
where
L: Default,
R: Default,
{
fn default() -> Self {
Self {
left: Default::default(),
right: Default::default(),
marker: Default::default(),
}
}
}
impl<C, L, R> Clone for Or<C, L, R>
where
L: Clone,
R: Clone,
{
fn clone(&self) -> Self {
Self {
left: self.left.clone(),
right: self.right.clone(),
marker: self.marker,
}
}
}
impl<C, L, R> Copy for Or<C, L, R>
where
L: Copy,
R: Copy,
{
}
impl<C, L, R> Or<C, L, R> {
pub const fn new(pat1: L, pat2: R) -> Self {
Self {
left: pat1,
right: pat2,
marker: PhantomData,
}
}
pub const fn left(&self) -> &L {
&self.left
}
pub const fn left_mut(&mut self) -> &mut L {
&mut self.left
}
pub const fn right(&self) -> &R {
&self.right
}
pub const fn right_mut(&mut self) -> &mut R {
&mut self.right
}
pub fn set_left(&mut self, left: L) -> &mut Self {
self.left = left;
self
}
pub fn set_right(&mut self, right: R) -> &mut Self {
self.right = right;
self
}
}
impl<'a, C, L, R, O, H> Ctor<C, O, H> for Or<C, L, R>
where
L: Ctor<C, O, H>,
R: Ctor<C, O, H>,
C: Match<'a>,
H: Handler<C>,
{
#[inline(always)]
fn construct(&self, ctx: &mut C, func: &mut H) -> Result<O, Error> {
let offset = ctx.offset();
debug_ctor_beg!("Or", offset);
let ret = debug_ctor_stage!("Or", "l", self.left.construct(ctx, func))
.or_else(|_| {
ctx.set_offset(offset);
debug_ctor_stage!("Or", "r", self.right.construct(ctx, func))
})
.inspect_err(|_| {
ctx.set_offset(offset);
});
debug_ctor_reval!("Or", offset, ctx.offset(), ret.is_ok());
ret
}
}
impl<'a, C, L, R> Regex<C> for Or<C, L, R>
where
L: Regex<C>,
R: Regex<C>,
C: Match<'a>,
{
#[inline(always)]
fn try_parse(&self, ctx: &mut C) -> Result<Span, Error> {
let offset = ctx.offset();
debug_regex_beg!("Or", offset);
let ret = debug_regex_stage!("Or", "l", ctx.try_mat(&self.left))
.or_else(|_| {
ctx.set_offset(offset);
debug_regex_stage!("Or", "r", ctx.try_mat(&self.right))
})
.inspect_err(|_| {
ctx.set_offset(offset);
});
debug_regex_reval!("Or", ret)
}
}