use core::fmt::Debug;
use core::marker::PhantomData;
use crate::ctor::Ctor;
use crate::ctor::Handler;
use crate::ctx::CtxGuard;
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 Enclose<C, P, L, R> {
pat: P,
open: L,
close: R,
marker: PhantomData<C>,
}
impl_not_for_regex!(Enclose<C, P, L, R>);
impl<C, P, L, R> Debug for Enclose<C, P, L, R>
where
P: Debug,
L: Debug,
R: Debug,
{
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
f.debug_struct("Enclose")
.field("pat", &self.pat)
.field("open", &self.open)
.field("close", &self.close)
.finish()
}
}
impl<C, P, L, R> Default for Enclose<C, P, L, R>
where
P: Default,
L: Default,
R: Default,
{
fn default() -> Self {
Self {
pat: Default::default(),
open: Default::default(),
close: Default::default(),
marker: Default::default(),
}
}
}
impl<C, P, L, R> Clone for Enclose<C, P, L, R>
where
P: Clone,
L: Clone,
R: Clone,
{
fn clone(&self) -> Self {
Self {
pat: self.pat.clone(),
open: self.open.clone(),
close: self.close.clone(),
marker: self.marker,
}
}
}
impl<C, P, L, R> Copy for Enclose<C, P, L, R>
where
P: Copy,
L: Copy,
R: Copy,
{
}
impl<C, P, L, R> Enclose<C, P, L, R> {
pub const fn new(pat: P, open: L, close: R) -> Self {
Self {
pat,
open,
close,
marker: PhantomData,
}
}
pub const fn pat(&self) -> &P {
&self.pat
}
pub const fn pat_mut(&mut self) -> &mut P {
&mut self.pat
}
pub const fn open(&self) -> &L {
&self.open
}
pub const fn open_mut(&mut self) -> &mut L {
&mut self.open
}
pub const fn close(&self) -> &R {
&self.close
}
pub const fn close_mut(&mut self) -> &mut R {
&mut self.close
}
pub fn set_pat(&mut self, pat: P) -> &mut Self {
self.pat = pat;
self
}
pub fn set_open(&mut self, open: L) -> &mut Self {
self.open = open;
self
}
pub fn set_close(&mut self, close: R) -> &mut Self {
self.close = close;
self
}
}
impl<'a, C, L, R, P, O, H> Ctor<C, O, H> for Enclose<C, P, L, R>
where
L: Regex<C>,
R: Regex<C>,
P: 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 mut ctx = CtxGuard::new(ctx);
debug_ctor_beg!("Enclose", ctx.beg());
let _ = debug_ctor_stage!("Enclose", "open", ctx.try_mat(&self.open)?);
let r = debug_ctor_stage!("Enclose", "pat", self.pat.construct(ctx.ctx(), func));
let r = ctx.process_ret(r)?;
let _ = debug_ctor_stage!("Enclose", "close", ctx.try_mat(&self.close)?);
debug_ctor_reval!("Enclose", ctx.beg(), ctx.end(), true);
Ok(r)
}
}
impl<'a, C, L, R, P> Regex<C> for Enclose<C, P, L, R>
where
L: Regex<C>,
R: Regex<C>,
P: Regex<C>,
C: Match<'a>,
{
#[inline(always)]
fn try_parse(&self, ctx: &mut C) -> Result<Span, Error> {
let mut ctx = CtxGuard::new(ctx);
debug_regex_beg!("Enclose", ctx.beg());
let mut ret = debug_regex_stage!("Enclose", "open", ctx.try_mat(&self.open)?);
ret.add_assign(debug_regex_stage!(
"Enclose",
"pat",
ctx.try_mat(&self.pat)?
));
ret.add_assign(debug_regex_stage!(
"Enclose",
"close",
ctx.try_mat(&self.close)?
));
debug_regex_reval!("Enclose", Ok(ret))
}
}