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_regex_beg;
use crate::debug_regex_reval;
use crate::err::Error;
use crate::regex::Regex;
use crate::regex::impl_not_for_regex;
use crate::span::Span;
pub struct OptionPat<C, P> {
pat: P,
marker: PhantomData<C>,
}
impl_not_for_regex!(OptionPat<C, P>);
impl<C, P> Debug for OptionPat<C, P>
where
P: Debug,
{
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
f.debug_struct("OptionPat").field("pat", &self.pat).finish()
}
}
impl<C, P> Default for OptionPat<C, P>
where
P: Default,
{
fn default() -> Self {
Self {
pat: Default::default(),
marker: Default::default(),
}
}
}
impl<C, P> Clone for OptionPat<C, P>
where
P: Clone,
{
fn clone(&self) -> Self {
Self {
pat: self.pat.clone(),
marker: self.marker,
}
}
}
impl<C, P> Copy for OptionPat<C, P> where P: Copy {}
impl<C, P> OptionPat<C, P> {
pub const fn new(pat: P) -> Self {
Self {
pat,
marker: PhantomData,
}
}
pub const fn pat(&self) -> &P {
&self.pat
}
pub const fn pat_mut(&mut self) -> &mut P {
&mut self.pat
}
pub fn set_pat(&mut self, pat: P) -> &mut Self {
self.pat = pat;
self
}
}
impl<'a, C, O, P, H> Ctor<C, Option<O>, H> for OptionPat<C, P>
where
P: Ctor<C, O, H>,
C: Match<'a>,
H: Handler<C>,
{
#[inline(always)]
fn construct(&self, ctx: &mut C, func: &mut H) -> Result<Option<O>, Error> {
let offset = ctx.offset();
debug_ctor_beg!("OptionPat", offset);
let ret = self
.pat
.construct(ctx, func)
.inspect_err(|_| {
ctx.set_offset(offset);
})
.ok();
debug_ctor_reval!("OptionPat", offset, ctx.offset(), ret.is_some());
Ok(ret)
}
}
impl<'a, C, P> Regex<C> for OptionPat<C, P>
where
P: Regex<C>,
C: Match<'a>,
{
#[inline(always)]
fn try_parse(&self, ctx: &mut C) -> Result<Span, Error> {
let offset = ctx.offset();
debug_regex_beg!("OptionPat", offset);
let ret = ctx
.try_mat(&self.pat)
.inspect_err(|_| {
ctx.set_offset(offset);
})
.or_else(|_| Ok(Span::new(offset, 0)));
debug_regex_reval!("OptionPat", ret)
}
}