use crate::tools::{AlwaysTool, CursorLen, CursorStart, Tool};
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
pub enum Either<L, R> {
L(L),
R(R),
}
impl<L, R> Either<L, R> {
pub fn map<LR, RR, LF: FnOnce(L) -> LR, RF: FnOnce(R) -> RR>(
self,
lf: LF,
rf: RF,
) -> Either<LR, RR> {
match self {
Self::L(l) => Either::L(lf(l)),
Self::R(r) => Either::R(rf(r)),
}
}
pub fn invert(self) -> Either<R, L> {
match self {
Self::L(l) => Either::R(l),
Self::R(r) => Either::L(r),
}
}
}
impl<L, R, E> Either<Result<L, E>, Result<R, E>> {
#[allow(clippy::missing_errors_doc)]
pub fn flatten(self) -> Result<Either<L, R>, E> {
match self {
Self::L(l) => l.map(Either::L),
Self::R(r) => r.map(Either::R),
}
}
}
impl<T> Either<T, T> {
pub fn merge(self) -> T {
match self {
Self::L(t) | Self::R(t) => t,
}
}
}
impl<T> Either<T, ::core::convert::Infallible> {
pub fn into_first(self) -> T {
match self {
Self::L(t) => t,
Self::R(imp) => match imp {},
}
}
}
impl<T> Either<::core::convert::Infallible, T> {
pub fn into_second(self) -> T {
match self {
Self::R(t) => t,
Self::L(imp) => match imp {},
}
}
}
pub(crate) trait InsertB<TD, SEPD> {
fn insert(&mut self, data: TD);
fn insert_sep(&mut self, data: SEPD);
}
#[derive(Debug, Copy, Clone, Default)]
pub(crate) struct Count(pub(crate) usize);
impl<TD, SEPD> InsertB<TD, SEPD> for Count {
fn insert(&mut self, _: TD) {
self.0 += 1;
}
fn insert_sep(&mut self, _: SEPD) {}
}
impl Count {
pub(crate) const fn new() -> Self {
Self(0)
}
}
#[cfg(feature = "alloc")]
impl<TD, SEPD> InsertB<TD, SEPD> for alloc::vec::Vec<TD> {
fn insert(&mut self, data: TD) {
self.push(data);
}
fn insert_sep(&mut self, _: SEPD) {}
}
pub(crate) fn ihelp<'a, T, SEP, I>(
atom: &T,
sep: &SEP,
st: CursorLen<'a, ()>,
vec: &mut I,
) -> Option<CursorLen<'a, ()>>
where
T: Tool<'a>,
SEP: Tool<'a>,
I: InsertB<T::Data, SEP::Data>,
{
st.chain(sep)
.ok()
.and_then(|d| d.chain_save(atom).ok())
.map(|d| {
d.map_data(|(sd, ad)| {
vec.insert_sep(sd);
vec.insert(ad);
})
})
}
pub(crate) fn ihelpe<'a, T, SEP, E, I>(
atom: &T,
sep: &SEP,
st: CursorLen<'a, ()>,
vec: &mut I,
) -> Result<CursorLen<'a, ()>, E>
where
T: Tool<'a, Error = E>,
SEP: Tool<'a, Error = E>,
I: InsertB<T::Data, SEP::Data>,
{
st.chain(sep).and_then(|d| d.chain_save(atom)).map(|d| {
d.map_data(|(sd, ad)| {
vec.insert_sep(sd);
vec.insert(ad);
})
})
}
pub struct Seq<F, S> {
pub first: F,
pub second: S,
}
impl<F, S> Seq<F, S> {
pub const fn new(first: F, second: S) -> Self {
Self { first, second }
}
}
impl<'a, F, S> Tool<'a> for Seq<F, S>
where
F: Tool<'a>,
S: Tool<'a>,
{
type Data = (F::Data, S::Data);
type Error = Either<F::Error, S::Error>;
fn parse(&self, c: CursorStart<'a>) -> Result<CursorLen<'a, Self::Data>, Self::Error> {
CursorLen::from(c)
.chain(&self.first)
.map_err(Either::L)?
.chain_save(&self.second)
.map_err(Either::R)
}
}
impl<'a, F, S> AlwaysTool<'a> for Seq<F, S>
where
F: AlwaysTool<'a>,
S: AlwaysTool<'a>,
{
fn parse_always(&self, c: CursorStart<'a>) -> CursorLen<'a, Self::Data> {
CursorLen::from(c)
.always(&self.first)
.always_save(&self.second)
}
}
pub struct Or<F, S> {
pub first: F,
pub second: S,
}
impl<'a, F, S> Tool<'a> for Or<F, S>
where
F: Tool<'a>,
S: Tool<'a>,
{
type Data = Either<F::Data, S::Data>;
type Error = (F::Error, S::Error);
fn parse(&self, c: CursorStart<'a>) -> Result<CursorLen<'a, Self::Data>, Self::Error> {
match self.first.parse(c) {
Ok(d) => Ok(d.map_data(Either::L)),
Err(f) => match self.second.parse(c) {
Ok(d) => Ok(d.map_data(Either::R)),
Err(s) => Err((f, s)),
},
}
}
}
impl<'a, F, S> AlwaysTool<'a> for Or<F, S>
where
F: AlwaysTool<'a>,
S: Tool<'a>,
{
fn parse_always(&self, c: CursorStart<'a>) -> CursorLen<'a, Self::Data> {
self.first.parse_always(c).map_data(Either::L)
}
}
#[derive(Debug, Copy, Clone, Default)]
pub struct Check<T>(pub T);
impl<'a, T> Tool<'a> for Check<T>
where
T: Tool<'a>,
{
type Error = T::Error;
type Data = T::Data;
fn parse(&self, c: CursorStart<'a>) -> Result<CursorLen<'a, Self::Data>, Self::Error> {
let d = self.0.parse(c)?;
Ok(CursorLen::<'_, ()>::from(c).map_data(|()| d.get_data().0))
}
}
#[derive(Debug, Copy, Clone, Default)]
pub struct CheckInv<T>(pub T);
impl<'a, T> Tool<'a> for CheckInv<T>
where
T: Tool<'a>,
{
type Error = T::Data;
type Data = T::Error;
fn parse(&self, c: CursorStart<'a>) -> Result<CursorLen<'a, Self::Data>, Self::Error> {
match self.0.parse(c) {
Ok(d) => Err(d.get_data().0),
Err(e) => Ok(CursorLen::<'_, ()>::from(c).map_data(|()| e)),
}
}
}
#[derive(Debug, Clone, Copy)]
pub struct RepeatAny<T, SEP> {
pub(crate) atom: T,
pub(crate) sep: SEP,
pub(crate) max: Option<usize>,
}
impl<T, SEP> RepeatAny<T, SEP> {
pub const fn new(atom: T, sep: SEP, max: Option<usize>) -> Self {
Self { atom, sep, max }
}
pub const fn new_bounds(atom: T, sep: SEP, max: usize) -> Self {
Self::new(atom, sep, Some(max))
}
pub const fn new_unbounded(atom: T, sep: SEP) -> Self {
Self::new(atom, sep, None)
}
}
impl<T, SEP> RepeatAny<T, SEP> {
fn parse_logic_continue<'a, I>(
&self,
mut st: CursorLen<'a, ()>,
vec: &mut I,
precount: usize,
) -> CursorLen<'a, ()>
where
T: Tool<'a>,
SEP: Tool<'a>,
I: InsertB<T::Data, SEP::Data>,
{
match self.max {
None => loop {
if let Some(tval) = ihelp(&self.atom, &self.sep, st, vec) {
st = tval;
} else {
break st;
}
},
Some(mx) => {
let mut i = precount;
loop {
if i >= mx {
break st;
} else if let Some(tval) = ihelp(&self.atom, &self.sep, st, vec) {
st = tval;
i += 1;
} else {
break st;
}
}
}
}
}
pub(crate) fn parse_logic<'a, I>(&self, st: CursorStart<'a>, vec: &mut I) -> CursorLen<'a, ()>
where
T: Tool<'a>,
SEP: Tool<'a>,
I: InsertB<T::Data, SEP::Data>,
{
if Some(0) == self.max {
CursorLen::from(st)
} else {
CursorLen::from(st).chain_err(&self.atom).map_or_else(
|t| t,
|tval| {
let (data, tval) = tval.get_data();
vec.insert(data);
self.parse_logic_continue(tval, vec, 1)
},
)
}
}
}
impl<'a, T, SEP> AlwaysTool<'a> for RepeatAny<T, SEP>
where
T: Tool<'a>,
SEP: Tool<'a>,
{
fn parse_always(&self, c: CursorStart<'a>) -> CursorLen<'a, Self::Data> {
let mut count = Count::new();
self.parse_logic(c, &mut count).map_data(|()| count.0)
}
}
impl<'a, T, SEP> Tool<'a> for RepeatAny<T, SEP>
where
T: Tool<'a>,
SEP: Tool<'a>,
{
type Data = usize;
type Error = ::core::convert::Infallible;
fn parse(&self, c: CursorStart<'a>) -> Result<CursorLen<'a, Self::Data>, Self::Error> {
Ok(self.parse_always(c))
}
}
#[derive(Debug, Clone, Copy)]
pub struct Repeat<T, SEP> {
pub(crate) sup: RepeatAny<T, SEP>,
pub(crate) min: usize,
}
impl<T, SEP> Repeat<T, SEP> {
pub fn new_bounds(atom: T, sep: SEP, min: usize, max: usize) -> Self {
assert!(
min <= max,
"Maximum value {max} is strictly less than minimum {min}"
);
Self {
sup: RepeatAny::new_bounds(atom, sep, max),
min,
}
}
pub const fn new_unbounded(atom: T, sep: SEP, min: usize) -> Self {
Self {
sup: RepeatAny::new_unbounded(atom, sep),
min,
}
}
}
impl<T, SEP> Repeat<T, SEP> {
pub(crate) fn parse_logic<'a, I, E>(
&self,
st: CursorStart<'a>,
vec: &mut I,
) -> Result<CursorLen<'a, ()>, E>
where
T: Tool<'a, Error = E>,
SEP: Tool<'a, Error = E>,
I: InsertB<T::Data, SEP::Data>,
{
if self.min > 0 {
let mut helper = {
let (data, h) = CursorLen::<'_, ()>::from(st)
.chain(&self.sup.atom)?
.get_data();
vec.insert(data);
h
};
for _ in 1..(self.min) {
helper = ihelpe(&self.sup.atom, &self.sup.sep, helper, vec)?;
}
Ok(self.sup.parse_logic_continue(helper, vec, self.min))
} else {
Ok(self.sup.parse_logic(st, vec))
}
}
}
impl<'a, T, SEP, E> Tool<'a> for Repeat<T, SEP>
where
T: Tool<'a, Error = E>,
SEP: Tool<'a, Error = E>,
{
type Data = usize;
type Error = E;
fn parse(&self, c: CursorStart<'a>) -> Result<CursorLen<'a, Self::Data>, Self::Error> {
let mut count = Count::new();
self.parse_logic(c, &mut count)
.map(|o| o.map_data(|()| count.0))
}
}
#[derive(Copy, Clone, Debug)]
pub struct LazyRepeatAny<T, SEP, TERM> {
atom: T,
sep: SEP,
term: TERM,
max: Option<usize>,
}
impl<T, SEP, TERM> LazyRepeatAny<T, SEP, TERM> {
pub const fn new_bounds(atom: T, sep: SEP, term: TERM, max: usize) -> Self {
Self {
atom,
sep,
term,
max: Some(max),
}
}
pub const fn new_unbounded(atom: T, sep: SEP, term: TERM) -> Self {
Self {
atom,
sep,
term,
max: None,
}
}
}
impl<T, SEP, TERM> LazyRepeatAny<T, SEP, TERM> {
pub(crate) fn parse_logic_continue<'a, I>(
&self,
mut st: CursorLen<'a, ()>,
vec: &mut I,
precount: usize,
) -> Result<CursorLen<'a, ()>, TERM::Error>
where
T: Tool<'a>,
SEP: Tool<'a>,
TERM: Tool<'a>,
I: InsertB<T::Data, SEP::Data>,
{
match self.max {
Some(mx) => {
let mut i = precount;
loop {
match st.chain_nodata(&self.term) {
Ok(hh) => {
break Ok(hh);
}
Err(e) => {
if i >= mx {
break Err(e);
} else if let Some(h) = ihelp(&self.atom, &self.sep, st, vec) {
st = h;
i += 1;
} else {
break Err(e);
}
}
}
}
}
None => loop {
match st.chain_nodata(&self.term) {
Ok(hh) => {
break Ok(hh);
}
Err(e) => {
if let Some(h) = ihelp(&self.atom, &self.sep, st, vec) {
st = h;
} else {
break Err(e);
}
}
}
},
}
}
pub(crate) fn parse_logic<'a, I>(
&self,
st: CursorStart<'a>,
vec: &mut I,
) -> Result<CursorLen<'a, ()>, TERM::Error>
where
T: Tool<'a>,
SEP: Tool<'a>,
TERM: Tool<'a>,
I: InsertB<T::Data, SEP::Data>,
{
let st = CursorLen::from(st);
if Some(0) == self.max {
st.chain_nodata(&self.term)
} else {
st.chain_nodata(&self.term).map_or_else(
|e| {
st.chain(&self.atom).map_or_else(
|_| Err(e),
|tval| {
let (i, h) = tval.get_data();
vec.insert(i);
self.parse_logic_continue(h, vec, 1)
},
)
},
Ok,
)
}
}
#[cfg(feature = "alloc")]
#[allow(clippy::missing_errors_doc)]
pub fn parse_store<'a>(
&self,
st: CursorStart<'a>,
vec: &mut alloc::vec::Vec<T::Data>,
) -> Result<CursorLen<'a, ()>, TERM::Error>
where
T: Tool<'a>,
SEP: Tool<'a>,
TERM: Tool<'a>,
{
self.parse_logic(st, vec)
}
}
impl<'a, T, SEP, TERM> Tool<'a> for LazyRepeatAny<T, SEP, TERM>
where
T: Tool<'a>,
SEP: Tool<'a>,
TERM: Tool<'a>,
{
type Data = usize;
type Error = TERM::Error;
fn parse(&self, c: CursorStart<'a>) -> Result<CursorLen<'a, Self::Data>, Self::Error> {
let mut count = Count::new();
let st = self.parse_logic(c, &mut count)?;
Ok(st.map_data(|()| count.0))
}
}
#[derive(Copy, Clone, Debug)]
pub struct LazyRepeat<T, SEP, TERM> {
sup: LazyRepeatAny<T, SEP, TERM>,
min: usize,
}
impl<T, SEP, TERM> LazyRepeat<T, SEP, TERM> {
pub fn new_bounds(atom: T, sep: SEP, term: TERM, min: usize, max: usize) -> Self {
assert!(
min <= max,
"Maximum value {max} is strictly less than minimum {min}"
);
Self {
sup: LazyRepeatAny::new_bounds(atom, sep, term, max),
min,
}
}
pub const fn new_unbounded(atom: T, sep: SEP, term: TERM, min: usize) -> Self {
Self {
sup: LazyRepeatAny::new_unbounded(atom, sep, term),
min,
}
}
}
impl<T, SEP, TERM> LazyRepeat<T, SEP, TERM> {
pub(crate) fn parse_logic<'a, E, I>(
&self,
st: CursorStart<'a>,
vec: &mut I,
) -> Result<CursorLen<'a, ()>, E>
where
T: Tool<'a, Error = E>,
SEP: Tool<'a, Error = E>,
TERM: Tool<'a, Error = E>,
I: InsertB<T::Data, SEP::Data>,
{
if self.min > 0 {
let mut helper = {
let (i, h) = CursorLen::from(st).chain(&self.sup.atom)?.get_data();
vec.insert(i);
h
};
for _ in 1..(self.min) {
helper = ihelpe(&self.sup.atom, &self.sup.sep, helper, vec)?;
}
self.sup.parse_logic_continue(helper, vec, self.min)
} else {
self.sup.parse_logic(st, vec)
}
}
#[cfg(feature = "alloc")]
#[allow(clippy::missing_errors_doc)]
pub fn parse_store<'a, E>(
&self,
st: CursorStart<'a>,
vec: &mut alloc::vec::Vec<T::Data>,
) -> Result<CursorLen<'a, ()>, E>
where
T: Tool<'a, Error = E>,
SEP: Tool<'a, Error = E>,
TERM: Tool<'a, Error = E>,
{
self.parse_logic(st, vec)
}
}
impl<'a, T, SEP, TERM, E> Tool<'a> for LazyRepeat<T, SEP, TERM>
where
T: Tool<'a, Error = E>,
SEP: Tool<'a, Error = E>,
TERM: Tool<'a, Error = E>,
{
type Data = usize;
type Error = E;
fn parse(&self, c: CursorStart<'a>) -> Result<CursorLen<'a, Self::Data>, Self::Error> {
let mut count = Count::new();
let st = self.parse_logic(c, &mut count)?;
Ok(st.map_data(|()| count.0))
}
}
#[cfg(feature = "alloc")]
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
pub struct VecStore<T>(pub T);
#[cfg(feature = "alloc")]
impl<'a, T, SEP, E> Tool<'a> for VecStore<Repeat<T, SEP>>
where
T: Tool<'a, Error = E>,
SEP: Tool<'a, Error = E>,
{
type Data = alloc::vec::Vec<T::Data>;
type Error = E;
fn parse(&self, c: CursorStart<'a>) -> Result<CursorLen<'a, Self::Data>, Self::Error> {
let mut count = alloc::vec::Vec::new();
let s = self.0.parse_logic(c, &mut count)?;
Ok(s.map_data(|()| count))
}
}
#[cfg(feature = "alloc")]
impl<'a, T, SEP> Tool<'a> for VecStore<RepeatAny<T, SEP>>
where
T: Tool<'a>,
SEP: Tool<'a>,
{
type Data = alloc::vec::Vec<T::Data>;
type Error = ::core::convert::Infallible;
fn parse(&self, c: CursorStart<'a>) -> Result<CursorLen<'a, Self::Data>, Self::Error> {
Ok(self.parse_always(c))
}
}
#[cfg(feature = "alloc")]
impl<'a, T, SEP> AlwaysTool<'a> for VecStore<RepeatAny<T, SEP>>
where
T: Tool<'a>,
SEP: Tool<'a>,
{
fn parse_always(&self, c: CursorStart<'a>) -> CursorLen<'a, Self::Data> {
let mut count = alloc::vec::Vec::new();
let s = self.0.parse_logic(c, &mut count);
s.map_data(|()| count)
}
}
#[cfg(feature = "alloc")]
impl<'a, T, SEP, TERM, E> Tool<'a> for VecStore<LazyRepeat<T, SEP, TERM>>
where
T: Tool<'a, Error = E>,
SEP: Tool<'a, Error = E>,
TERM: Tool<'a, Error = E>,
{
type Data = alloc::vec::Vec<T::Data>;
type Error = E;
fn parse(&self, c: CursorStart<'a>) -> Result<CursorLen<'a, Self::Data>, Self::Error> {
let mut count = alloc::vec::Vec::new();
let s = self.0.parse_logic(c, &mut count)?;
Ok(s.map_data(|()| count))
}
}
#[cfg(feature = "alloc")]
impl<'a, T, TERM, SEP> Tool<'a> for VecStore<LazyRepeatAny<T, SEP, TERM>>
where
T: Tool<'a>,
SEP: Tool<'a>,
TERM: Tool<'a>,
{
type Data = alloc::vec::Vec<T::Data>;
type Error = TERM::Error;
fn parse(&self, c: CursorStart<'a>) -> Result<CursorLen<'a, Self::Data>, Self::Error> {
let mut count = alloc::vec::Vec::new();
let s = self.0.parse_logic(c, &mut count)?;
Ok(s.map_data(|()| count))
}
}