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::err::Error;
use crate::map::Select0;
use crate::map::Select1;
use crate::map::SelectEq;
use crate::neu::CRange;
use crate::regex::Regex;
use crate::regex::impl_not_for_regex;
use crate::span::Span;
use super::Map;
use crate::debug_ctor_beg;
use crate::debug_ctor_reval;
use crate::debug_regex_beg;
use crate::debug_regex_reval;
pub struct SepOnce<C, L, S, R> {
left: L,
sep: S,
right: R,
marker: PhantomData<C>,
}
impl_not_for_regex!(SepOnce<C, L, S, R>);
impl<C, L, S, R> Debug for SepOnce<C, L, S, R>
where
L: Debug,
S: Debug,
R: Debug,
{
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
f.debug_struct("SepOnce")
.field("left", &self.left)
.field("sep", &self.sep)
.field("right", &self.right)
.finish()
}
}
impl<C, L, S, R> Default for SepOnce<C, L, S, R>
where
L: Default,
S: Default,
R: Default,
{
fn default() -> Self {
Self {
left: Default::default(),
sep: Default::default(),
right: Default::default(),
marker: Default::default(),
}
}
}
impl<C, L, S, R> Clone for SepOnce<C, L, S, R>
where
L: Clone,
S: Clone,
R: Clone,
{
fn clone(&self) -> Self {
Self {
left: self.left.clone(),
sep: self.sep.clone(),
right: self.right.clone(),
marker: self.marker,
}
}
}
impl<C, L, S, R> Copy for SepOnce<C, L, S, R>
where
L: Copy,
S: Copy,
R: Copy,
{
}
impl<C, L, S, R> SepOnce<C, L, S, R> {
pub const fn new(left: L, sep: S, right: R) -> Self {
Self {
left,
sep,
right,
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 sep(&self) -> &S {
&self.sep
}
pub const fn sep_mut(&mut self) -> &mut S {
&mut self.sep
}
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
}
pub fn set_sep(&mut self, sep: S) -> &mut Self {
self.sep = sep;
self
}
pub fn _0<O>(self) -> Map<C, Self, Select0, O> {
Map::new(self, Select0)
}
pub fn _1<O>(self) -> Map<C, Self, Select1, O> {
Map::new(self, Select1)
}
pub fn _eq<I1, I2>(self) -> Map<C, Self, SelectEq, (I1, I2)> {
Map::new(self, SelectEq)
}
}
impl<'a, C, L, S, R, O1, O2, H> Ctor<C, (O1, O2), H> for SepOnce<C, L, S, R>
where
L: Ctor<C, O1, H>,
R: Ctor<C, O2, H>,
S: Regex<C>,
C: Match<'a>,
H: Handler<C>,
{
#[inline(always)]
fn construct(&self, ctx: &mut C, func: &mut H) -> Result<(O1, O2), Error> {
let mut ctx = CtxGuard::new(ctx);
debug_ctor_beg!("SepOnce", ctx.beg());
let r = self.left.construct(ctx.ctx(), func);
let r = ctx.process_ret(r)?;
let _ = ctx.try_mat(&self.sep)?;
let l = self.right.construct(ctx.ctx(), func);
let l = ctx.process_ret(l)?;
debug_ctor_reval!("SepOnce", ctx.beg(), ctx.end(), true);
Ok((r, l))
}
}
impl<'a, C, L, S, R> Regex<C> for SepOnce<C, L, S, R>
where
S: Regex<C>,
L: Regex<C>,
R: Regex<C>,
C: Match<'a>,
{
#[inline(always)]
fn try_parse(&self, ctx: &mut C) -> Result<Span, Error> {
let mut ctx = CtxGuard::new(ctx);
let mut span = Span::new(ctx.beg(), 0);
debug_regex_beg!("SepOnce", ctx.beg());
span.add_assign(ctx.try_mat(&self.left)?);
span.add_assign(ctx.try_mat(&self.sep)?);
span.add_assign(ctx.try_mat(&self.right)?);
debug_regex_reval!("SepOnce", Ok(span))
}
}
#[cfg(feature = "alloc")]
mod alloc_sep {
use crate::ctor::Ctor;
use crate::ctor::Handler;
use crate::ctx::Match;
use crate::err::Error;
use crate::neu::CRange;
use crate::regex::Regex;
use crate::span::Span;
use core::fmt::Debug;
use core::marker::PhantomData;
use crate::debug_ctor_beg;
use crate::debug_ctor_reval;
use crate::debug_regex_beg;
use crate::debug_regex_reval;
use crate::regex::impl_not_for_regex;
pub struct Separate<C, P, S> {
pat: P,
sep: S,
skip: bool,
capacity: usize,
min: usize,
marker: PhantomData<C>,
}
impl_not_for_regex!(Separate<C, P, S>);
impl<C, P, S> Debug for Separate<C, P, S>
where
P: Debug,
S: Debug,
{
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
f.debug_struct("Separate")
.field("pat", &self.pat)
.field("sep", &self.sep)
.field("skip", &self.skip)
.field("capacity", &self.capacity)
.field("min", &self.min)
.finish()
}
}
impl<C, P, S> Default for Separate<C, P, S>
where
P: Default,
S: Default,
{
fn default() -> Self {
Self {
pat: Default::default(),
sep: Default::default(),
skip: Default::default(),
capacity: Default::default(),
min: Default::default(),
marker: Default::default(),
}
}
}
impl<C, P, S> Clone for Separate<C, P, S>
where
P: Clone,
S: Clone,
{
fn clone(&self) -> Self {
Self {
pat: self.pat.clone(),
sep: self.sep.clone(),
skip: self.skip,
capacity: self.capacity,
min: self.min,
marker: self.marker,
}
}
}
impl<C, P, S> Copy for Separate<C, P, S>
where
P: Copy,
S: Copy,
{
}
impl<C, P, S> Separate<C, P, S> {
pub const fn new(pat: P, sep: S) -> Self {
Self {
pat,
sep,
skip: true,
capacity: 0,
min: 1,
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 sep(&self) -> &S {
&self.sep
}
pub const fn sep_mut(&mut self) -> &mut S {
&mut self.sep
}
pub const fn skip(&self) -> bool {
self.skip
}
pub const fn min(&self) -> usize {
self.min
}
pub const fn capacity(&self) -> usize {
self.capacity
}
pub fn set_pat(&mut self, pat: P) -> &mut Self {
self.pat = pat;
self
}
pub fn set_sep(&mut self, sep: S) -> &mut Self {
self.sep = sep;
self
}
pub fn set_skip(&mut self, skip: bool) -> &mut Self {
self.skip = skip;
self
}
pub fn set_capacity(&mut self, capacity: usize) -> &mut Self {
self.capacity = capacity;
self
}
pub fn set_min(&mut self, min: usize) -> &mut Self {
self.min = min;
self
}
pub fn with_skip(mut self, skip: bool) -> Self {
self.skip = skip;
self
}
pub fn with_capacity(mut self, capacity: usize) -> Self {
self.capacity = capacity;
self
}
pub fn at_least(mut self, min: usize) -> Self {
self.min = min;
self
}
}
impl<'a, C, S, P, O, H> Ctor<C, crate::alloc::Vec<O>, H> for Separate<C, P, S>
where
P: Ctor<C, O, H>,
S: Regex<C>,
C: Match<'a>,
H: Handler<C>,
{
#[inline(always)]
fn construct(&self, ctx: &mut C, func: &mut H) -> Result<crate::alloc::Vec<O>, Error> {
let offset: usize = ctx.offset();
let mut vals = crate::alloc::Vec::with_capacity(self.capacity.max(self.min));
let range: CRange<usize> = (self.min..).into();
debug_ctor_beg!("Separate", range, offset);
while let Ok(val) = self.pat.construct(ctx, func) {
let s_span = ctx.try_mat(&self.sep);
if s_span.is_ok() || self.skip {
vals.push(val);
}
if s_span.is_err() {
break;
}
}
let ret = if vals.len() >= self.min {
Ok(vals)
} else {
Err(Error::Separate)
}
.inspect_err(|_| {
ctx.set_offset(offset);
});
debug_ctor_reval!("Separate", range, offset, ctx.offset(), ret.is_ok());
ret
}
}
impl<'a, C, S, P> Regex<C> for Separate<C, P, S>
where
S: Regex<C>,
P: Regex<C>,
C: Match<'a>,
{
#[inline(always)]
fn try_parse(&self, ctx: &mut C) -> Result<Span, Error> {
let offset = ctx.offset();
let mut cnt = 0;
let mut total = Span::new(offset, 0);
let range: CRange<usize> = (self.min..).into();
debug_regex_beg!("Separate", range, offset);
while let Ok(p_span) = ctx.try_mat(&self.pat) {
let s_span = ctx.try_mat(&self.sep);
if s_span.is_ok() || self.skip {
cnt += 1;
total.add_assign(p_span);
if let Ok(sep_ret) = s_span {
total.add_assign(sep_ret);
}
}
if s_span.is_err() {
break;
}
}
let ret = if cnt >= self.min {
Ok(total)
} else {
Err(Error::Separate)
}
.inspect_err(|_| {
ctx.set_offset(offset);
});
debug_regex_reval!("Separate", range, ret)
}
}
}
#[cfg(feature = "alloc")]
pub use alloc_sep::*;
pub struct Separate2<C, P, S, const M: usize, const N: usize> {
pat: P,
sep: S,
skip: bool,
marker: PhantomData<C>,
}
impl<C, P, S, const M: usize, const N: usize> core::ops::Not for Separate2<C, P, S, M, N> {
type Output = crate::regex::Assert<Self>;
fn not(self) -> Self::Output {
crate::regex::not(self)
}
}
impl<C, P, S, const M: usize, const N: usize> Debug for Separate2<C, P, S, M, N>
where
P: Debug,
S: Debug,
{
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
f.debug_struct("Separate2")
.field("pat", &self.pat)
.field("sep", &self.sep)
.field("skip", &self.skip)
.finish()
}
}
impl<C, P, S, const M: usize, const N: usize> Default for Separate2<C, P, S, M, N>
where
P: Default,
S: Default,
{
fn default() -> Self {
Self {
pat: Default::default(),
sep: Default::default(),
skip: Default::default(),
marker: Default::default(),
}
}
}
impl<C, P, S, const M: usize, const N: usize> Clone for Separate2<C, P, S, M, N>
where
P: Clone,
S: Clone,
{
fn clone(&self) -> Self {
Self {
pat: self.pat.clone(),
sep: self.sep.clone(),
skip: self.skip,
marker: self.marker,
}
}
}
impl<C, P, S, const M: usize, const N: usize> Copy for Separate2<C, P, S, M, N>
where
P: Copy,
S: Copy,
{
}
impl<C, P, S, const M: usize, const N: usize> Separate2<C, P, S, M, N> {
pub const fn new(pat: P, sep: S) -> Self {
Self {
pat,
sep,
skip: true,
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 sep(&self) -> &S {
&self.sep
}
pub const fn sep_mut(&mut self) -> &mut S {
&mut self.sep
}
pub const fn skip(&self) -> bool {
self.skip
}
pub fn set_pat(&mut self, pat: P) -> &mut Self {
self.pat = pat;
self
}
pub fn set_sep(&mut self, sep: S) -> &mut Self {
self.sep = sep;
self
}
pub fn set_skip(&mut self, skip: bool) -> &mut Self {
self.skip = skip;
self
}
pub fn with_skip(mut self, skip: bool) -> Self {
self.skip = skip;
self
}
}
impl<'a, C, S, P, O, H, const M: usize, const N: usize> Ctor<C, [Option<O>; N], H>
for Separate2<C, P, S, M, N>
where
P: Ctor<C, O, H>,
S: Regex<C>,
C: Match<'a>,
H: Handler<C>,
{
#[inline(always)]
fn construct(&self, ctx: &mut C, func: &mut H) -> Result<[Option<O>; N], Error> {
let offset: usize = ctx.offset();
let mut vals = [const { None }; N];
let mut cnt = 0;
let range = M..=N;
debug_ctor_beg!("Separate2", &range, offset);
while cnt <= N {
if let Ok(val) = self.pat.construct(ctx, func) {
let s_span = ctx.try_mat(&self.sep);
if s_span.is_ok() || self.skip {
vals[cnt] = Some(val);
cnt += 1;
}
if s_span.is_err() {
break;
}
} else {
break;
}
}
let ret = if cnt >= M {
Ok(vals)
} else {
Err(Error::Separate2)
}
.inspect_err(|_| {
ctx.set_offset(offset);
});
debug_ctor_reval!("Separate2", range, offset, ctx.offset(), ret.is_ok());
ret
}
}
impl<'a, C, S, P, const M: usize, const N: usize> Regex<C> for Separate2<C, P, S, M, N>
where
S: Regex<C>,
P: Regex<C>,
C: Match<'a>,
{
#[inline(always)]
fn try_parse(&self, ctx: &mut C) -> Result<Span, Error> {
let offset = ctx.offset();
let mut cnt = 0;
let mut total = Span::new(offset, 0);
let range = M..=N;
debug_regex_beg!("Separate2", &range, offset);
while cnt <= N {
if let Ok(p_span) = ctx.try_mat(&self.pat) {
let s_span = ctx.try_mat(&self.sep);
if s_span.is_ok() || self.skip {
cnt += 1;
total.add_assign(p_span);
if let Ok(sep_ret) = s_span {
total.add_assign(sep_ret);
}
}
if s_span.is_err() {
break;
}
} else {
break;
}
}
let ret = if cnt >= M {
Ok(total)
} else {
Err(Error::Separate2)
}
.inspect_err(|_| {
ctx.set_offset(offset);
});
debug_regex_reval!("Separate2", range, ret)
}
}
pub struct SepCollect<C, P, S, O, V> {
pat: P,
sep: S,
skip: bool,
min: usize,
marker: PhantomData<(C, O, V)>,
}
impl_not_for_regex!(SepCollect<C, P, S, O, V>);
impl<C, P, S, O, V> Debug for SepCollect<C, P, S, O, V>
where
P: Debug,
S: Debug,
{
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
f.debug_struct("SepCollect")
.field("pat", &self.pat)
.field("sep", &self.sep)
.field("skip", &self.skip)
.field("min", &self.min)
.finish()
}
}
impl<C, P, S, O, V> Default for SepCollect<C, P, S, O, V>
where
P: Default,
S: Default,
{
fn default() -> Self {
Self {
pat: Default::default(),
sep: Default::default(),
skip: Default::default(),
min: Default::default(),
marker: Default::default(),
}
}
}
impl<C, P, S, O, V> Clone for SepCollect<C, P, S, O, V>
where
P: Clone,
S: Clone,
{
fn clone(&self) -> Self {
Self {
pat: self.pat.clone(),
sep: self.sep.clone(),
skip: self.skip,
min: self.min,
marker: self.marker,
}
}
}
impl<C, P, S, O, V> Copy for SepCollect<C, P, S, O, V>
where
P: Copy,
S: Copy,
{
}
impl<C, P, S, O, V> SepCollect<C, P, S, O, V> {
pub const fn new(pat: P, sep: S) -> Self {
Self {
pat,
sep,
skip: true,
min: 1,
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 sep(&self) -> &S {
&self.sep
}
pub const fn sep_mut(&mut self) -> &mut S {
&mut self.sep
}
pub const fn skip(&self) -> bool {
self.skip
}
pub const fn min(&self) -> usize {
self.min
}
pub fn set_pat(&mut self, pat: P) -> &mut Self {
self.pat = pat;
self
}
pub fn set_sep(&mut self, sep: S) -> &mut Self {
self.sep = sep;
self
}
pub fn set_skip(&mut self, skip: bool) -> &mut Self {
self.skip = skip;
self
}
pub fn set_min(&mut self, min: usize) -> &mut Self {
self.min = min;
self
}
pub fn with_skip(mut self, skip: bool) -> Self {
self.skip = skip;
self
}
pub fn at_least(mut self, min: usize) -> Self {
self.min = min;
self
}
}
impl<'a, C, S, P, O, V, H> Ctor<C, V, H> for SepCollect<C, P, S, O, V>
where
V: FromIterator<O>,
P: Ctor<C, O, H>,
S: Regex<C>,
C: Match<'a>,
H: Handler<C>,
{
#[inline(always)]
fn construct(&self, ctx: &mut C, func: &mut H) -> Result<V, Error> {
let offset = ctx.offset();
let mut cnt = 0;
let mut end = false;
let range: CRange<usize> = (self.min..).into();
let ret = {
debug_ctor_beg!("SepCollect", range, offset);
V::from_iter(core::iter::from_fn(|| {
self.pat.construct(ctx, func).ok().and_then(|ret| {
let s_span = ctx.try_mat(&self.sep);
if !end {
if s_span.is_err() {
end = true;
}
if s_span.is_ok() || self.skip {
cnt += 1;
return Some(ret);
}
}
None
})
}))
};
let ret = if cnt >= self.min {
Ok(ret)
} else {
Err(Error::SepCollect)
}
.inspect_err(|_| {
ctx.set_offset(offset);
});
debug_ctor_reval!("SepCollect", range, offset, ctx.offset(), ret.is_ok());
ret
}
}
impl<'a, C, S, P, O, V> Regex<C> for SepCollect<C, P, S, O, V>
where
S: Regex<C>,
P: Regex<C>,
C: Match<'a>,
{
#[inline(always)]
fn try_parse(&self, ctx: &mut C) -> Result<Span, Error> {
let offset = ctx.offset();
let mut cnt = 0;
let mut total = Span::new(offset, 0);
let range: CRange<usize> = (self.min..).into();
debug_regex_beg!("SepCollect", range, offset);
while let Ok(p_span) = ctx.try_mat(&self.pat) {
let s_span = ctx.try_mat(&self.sep);
if s_span.is_ok() || self.skip {
cnt += 1;
total.add_assign(p_span);
if let Ok(sep_ret) = s_span {
total.add_assign(sep_ret);
}
}
if s_span.is_err() {
break;
}
}
let ret = if cnt >= self.min {
Ok(total)
} else {
Err(Error::SepCollect)
}
.inspect_err(|_| {
ctx.set_offset(offset);
});
debug_regex_reval!("SepCollect", range, ret)
}
}