use crate::tools::{Tool, AlwaysTool, View};
#[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 {}
}
}
}
mod _priv {
use super::{Tool, View};
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
pub struct TupData<D, M>{
pub(crate) data : D,
pub(crate) this : M,
pub(crate) len : usize
}
pub(crate) type TupVal<M> = TupData<(), M>;
impl<D, M> TupData<D, M>{
pub fn new(this : M) -> Self where D : Default {
Self{this, data : D::default(), len : 0}
}
pub fn map_data<DD, F : FnOnce(D) -> DD>(self, f : F) -> TupData<DD, M> {
TupData{this : self.this, len : self.len, data : f(self.data)}
}
pub fn get_data(self) -> (D, TupData<(), M>) {
(self.data, TupData{this : self.this, len : self.len, data : ()})
}
pub fn finalize(self) -> (D, usize, M) {
(self.data, self.len, self.this)
}
}
impl<'a, D> TupData<D, View<'a>> {
#[allow(clippy::missing_errors_doc)]
pub fn chain_replace<T>(self, t : &T) -> Result<TupData<T::Data, View<'a>>, T::Error> where T : Tool<'a> {
self.chain_map(t, |_, b, _| b)
}
#[allow(clippy::missing_errors_doc)]
pub fn chain_nodata<T>(self, t : &T) -> Result<Self, T::Error> where T : Tool<'a> {
self.chain_map(t, |a, _, _| a)
}
#[allow(clippy::missing_errors_doc)]
#[allow(clippy::type_complexity)]
pub fn chain_save<T>(self, t : &T) -> Result<TupData<(D, T::Data), View<'a>>, T::Error> where T : Tool<'a> {
self.chain_map(t, |a, b, _| (a, b))
}
#[allow(clippy::missing_errors_doc)]
#[allow(clippy::type_complexity)]
#[allow(dead_code)]
pub fn chain_save_out<T>(self, t : &T) -> Result<(Self, T::Data), T::Error> where T : Tool<'a> {
self.this.match_tool_data_len(t)
.map(|(data, len, this)| (TupData{this, data : self.data, len : len + self.len}, data))
}
#[allow(clippy::missing_errors_doc)]
#[allow(clippy::type_complexity)]
#[allow(dead_code)]
pub fn chain_save_at<T>(self, t : &T, to : &mut T::Data) -> Result<Self, T::Error> where T : Tool<'a> {
self.chain_map(t, |a, b, _| {*to = b; a} )
}
pub(crate) fn chain_map<T, F, O>(self, t : &T, f : F) -> Result<TupData<O, View<'a>>, T::Error> where
T : Tool<'a>,
F : FnOnce(D, T::Data, usize) -> O
{
self.this.match_tool_data_len(t)
.map(|(data, len, this)| TupData{this, data : f(self.data, data, len), len : len + self.len})
}
}
impl<'a> TupData<(), View<'a>>{
#[allow(clippy::missing_errors_doc)]
pub fn chain<T>(self, t : &T) -> Result<TupData<T::Data, View<'a>>, T::Error> where T : Tool<'a> {
self.chain_replace(t)
}
}
}
#[cfg(any(feature="unstable-features", doc))]
pub use _priv::*;
#[cfg(not(any(feature="unstable-features", doc)))]
pub(crate) use _priv::*;
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 : TupVal<View<'a>>, vec : &mut I) -> Option<TupVal<View<'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 : TupVal<View<'a>>, vec : &mut I) -> Result<TupVal<View<'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, st : View<'a>) -> Result<(Self::Data, usize, View<'a>), Self::Error> {
TupData::new(st)
.chain(&self.first)
.map_err(Either::L)?
.chain_save(&self.second)
.map_err(Either::R)
.map(TupData::finalize)
}
}
impl<'a, F, S> AlwaysTool<'a> for Seq<F, S> where F : AlwaysTool<'a>, S : AlwaysTool<'a> {
fn parse_always(&self, st : View<'a>) -> (Self::Data, usize, View<'a>) {
let (d0, l0, st) = self.first.parse_always(st);
let (d1, l1, st) = self.second.parse_always(st);
((d0, d1), l0 + l1, st)
}
}
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, st : View<'a>) -> Result<(Self::Data, usize, View<'a>), Self::Error> {
match self.first.parse(st) {
Ok(d) => Ok((Either::L(d.0), d.1, d.2)),
Err(f) => match self.second.parse(st) {
Ok(d) => Ok((Either::R(d.0), d.1, d.2)),
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, st : View<'a>) -> (Self::Data, usize, View<'a>) {
let (d, l, st) = self.first.parse_always(st);
(Either::L(d), l, st)
}
}
#[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, st : View<'a>) -> Result<(Self::Data, usize, View<'a>), Self::Error> {
let d = self.0.parse(st)?;
Ok((d.0, 0, st))
}
}
#[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, st : View<'a>) -> Result<(Self::Data, usize, View<'a>), Self::Error> {
match self.0.parse(st) {
Ok(d) => Err(d.0),
Err(e) => Ok((e, 0, st))
}
}
}
#[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 : TupVal<View<'a>>, vec : &mut I, precount : usize) -> TupVal<View<'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 : View<'a>, vec : &mut I) -> TupVal<View<'a>> where
T : Tool<'a>,
SEP : Tool<'a>,
I : InsertB<T::Data, SEP::Data>
{
if Some(0) == self.max {
TupData::new(st)
}
else {
TupData::new(st).chain(&self.atom)
.map_or_else(
|_| TupData::new(st),
|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, st : View<'a>) -> (Self::Data, usize, View<'a>) {
let mut count = Count::new();
let ((), l, s) = self.parse_logic(st, &mut count).finalize();
(count.0, l, s)
}
}
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, st : View<'a>) -> Result<(Self::Data, usize, View<'a>), Self::Error> {
Ok(self.parse_always(st))
}
}
#[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 : View<'a>, vec : &mut I) -> Result<TupVal<View<'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) = TupVal::new(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, st : View<'a>) -> Result<(Self::Data, usize, View<'a>), Self::Error> {
let mut count = Count::new();
let ((), l, s) = self.parse_logic(st, &mut count)?.finalize();
Ok((count.0, l, s))
}
}
#[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 : TupVal<View<'a>>, vec : &mut I, precount : usize) -> Result<TupVal<View<'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 : View<'a>, vec : &mut I) -> Result<TupVal<View<'a>>, TERM::Error> where
T : Tool<'a>,
SEP : Tool<'a>,
TERM : Tool<'a>,
I : InsertB<T::Data, SEP::Data>
{
let st = TupVal::new(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 : View<'a>, vec : &mut alloc::vec::Vec<T::Data>) -> Result<View<'a>, TERM::Error> where
T : Tool<'a>,
SEP : Tool<'a>,
TERM : Tool<'a>
{
self.parse_logic(st, vec)
.map(|d| d.finalize().2)
}
#[allow(clippy::missing_errors_doc)]
pub fn parse_count<'a>(&self, st : View<'a>) -> Result<(usize, usize, View<'a>), TERM::Error> where
T : Tool<'a>,
SEP : Tool<'a>,
TERM : Tool<'a>
{
let mut count = Count::new();
let st = self.parse_logic(st, &mut count)?;
Ok((count.0, st.len, st.this))
}
}
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, st : View<'a>) -> Result<(Self::Data, usize, View<'a>), Self::Error> {
let mut count = Count::new();
let ((), l, s) = self.parse_logic(st, &mut count)?.finalize();
Ok((count.0, l, s))
}
}
#[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 : View<'a>, vec : &mut I) -> Result<TupVal<View<'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) = TupVal::new(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 : View<'a>, vec : &mut alloc::vec::Vec<T::Data>) -> Result<View<'a>, E>
where T : Tool<'a, Error = E>,
SEP : Tool<'a, Error = E>,
TERM : Tool<'a, Error = E> {
self.parse_logic(st, vec)
.map(|d| d.finalize().2)
}
}
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, st : View<'a>) -> Result<(Self::Data, usize, View<'a>), Self::Error> {
let mut count = Count::new();
let ((), l, s) = self.parse_logic(st, &mut count)?.finalize();
Ok((count.0, l, s))
}
}
#[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, st : View<'a>) -> Result<(Self::Data, usize, View<'a>), Self::Error> {
let mut count = alloc::vec::Vec::new();
let ((), l, s) = self.0.parse_logic(st, &mut count)?.finalize();
Ok((count, l, s))
}
}
#[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, st : View<'a>) -> Result<(Self::Data, usize, View<'a>), Self::Error> {
Ok(self.parse_always(st))
}
}
#[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, st : View<'a>) -> (Self::Data, usize, View<'a>) {
let mut count = alloc::vec::Vec::new();
let ((), l, s) = self.0.parse_logic(st, &mut count).finalize();
(count, l, s)
}
}
#[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, st : View<'a>) -> Result<(Self::Data, usize, View<'a>), Self::Error> {
let mut count = alloc::vec::Vec::new();
let ((), l, s) = self.0.parse_logic(st, &mut count)?.finalize();
Ok((count, l, s))
}
}
#[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, st : View<'a>) -> Result<(Self::Data, usize, View<'a>), Self::Error> {
let mut count = alloc::vec::Vec::new();
let ((), l, s) = self.0.parse_logic(st, &mut count)?.finalize();
Ok((count, l, s))
}
}