use core::ops::{Index, Range, RangeTo};
#[allow(clippy::wildcard_imports)]
use super::*;
#[macro_export]
macro_rules! err {
    ($($vis: vis $name: ident: $message: literal),*$(,)?) => {$(
        #[derive(Debug, Copy, Clone, Default)]
        #[doc = $message]
        $vis struct $name;
        impl ::core::fmt::Display for $name {
            fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
                write!(f, $message)
            }
        }
        impl ::core::error::Error for $name {}
    )*};
}
#[derive(Debug, Clone, PartialEq, NamedRule)]
pub struct Map<
    'input, SliceType: ?Sized, 
    R: Rule<'input, SliceType>, O, 
    Func: Fn(R::Output) -> O
> {
    pub(crate) inner: R,
    pub(crate) func: Func,
    pub(crate) _p: PhantomData<(&'input SliceType, O)>
}
impl<
    'input, SliceType: ?Sized, 
    R: Rule<'input, SliceType>, O, 
    Func: Fn(R::Output) -> O
> Rule<'input, SliceType> for Map<'input, SliceType, R, O, Func> {
    type Output = Func::Output;
    fn parse_at<'cursor, 'this, 'index>(&'this self, input: &'cursor mut &'input SliceType, index: &'index mut usize)
        -> Result<Self::Output, ParseError> where 'input: 'this 
    {
        self.inner.parse_at(input, index)
            .map(&self.func)
    }
}
#[derive(Debug, Clone, PartialEq, NamedRule)]
pub struct TryMap<
    'input, SliceType: ?Sized, 
    R: Rule<'input, SliceType>, O, E: Error + 'static,
    Func: Fn(R::Output) -> Result<O, E>
> {
    pub(crate) inner: R,
    pub(crate) func: Func,
    pub(crate) _p: PhantomData<(&'input SliceType, O)>
}
impl<
    'input, SliceType: ?Sized, 
    R: Rule<'input, SliceType>, O, E: Error + 'static,
    Func: Fn(R::Output) -> Result<O, E>
> Rule<'input, SliceType> for TryMap<'input, SliceType, R, O, E, Func> {
    type Output = O;
    fn parse_at<'cursor, 'this, 'index>(&'this self, input: &'cursor mut &'input SliceType, index: &'index mut usize)
        -> Result<Self::Output, ParseError> where 'input: 'this 
    {
        let start_index = *index;
        let start_input = *input;
        self.inner.parse_at(input, index)
            .and_then(|res| (self.func)(res)
                .map_err(|err| {
                    *index = start_index;
                    *input = start_input;
                    ParseError::new(Some(Box::new(err)), self.inner.name(), start_index)
                })
            )
    }
}
#[derive(Debug, Clone, PartialEq, NamedRule)]
pub struct Not<R>(pub(crate) R);
impl<'input, T: ?Sized + 'input, R: Rule<'input, T>> Rule<'input, T> for Not<R> {
    type Output = ();
    fn parse_at<'cursor, 'this, 'index>(&'this self, input: &'cursor mut &'input T, index: &'index mut usize) -> Result<Self::Output, ParseError> where 'input: 'this {
        let start = *index;
        let res = self.0.parse_at(input, index);
        *index = start;
        let Err(_) = res else {
            return Err(ParseError::new(
                Some(Box::new(UnexpectedMatch)),
                self.name(), start
            ));
        };
        Ok(())
    }
}
#[derive(NamedRule)]
pub struct Attempt<'input, T: 'input + ?Sized, R: Rule<'input, T>>(pub R, pub(crate) PhantomData<&'input T>);
impl<'input, T: 'input + ?Sized, R: Rule<'input, T>> Rule<'input, T> for Attempt<'input, T, R> {
    type Output = Result<R::Output, ParseError>;
    
    fn parse_at<'cursor, 'this, 'index>(&'this self, input: &'cursor mut &'input T, index: &'index mut usize) -> Result<Self::Output, ParseError> where 'input: 'this {
        let before = (*input, *index);
        let res = self.0.parse_at(input, index);
        if res.is_err() { (*input, *index) = before; }
        Ok(res)
    }
}
#[derive(NamedRule)]
pub struct Consume<'input, T: 'input + ?Sized, R: Rule<'input, T>>(pub R, pub(crate) PhantomData<&'input T>);
impl<'input, R: Rule<'input, str>> Rule<'input, str> for Consume<'input, str, R> {
    type Output = Vec<R::Output>;
    
    fn parse_at<'cursor, 'this, 'index>(&'this self, input: &'cursor mut &'input str, index: &'index mut usize) -> Result<Self::Output, ParseError> where 'input: 'this {
        let before = (*input, *index);
        let mut els = Vec::new();
        while !input.is_empty() {
            let el = match self.0.parse_at(input, index) {
                Ok(v) => v,
                Err(err) => { (*input, *index) = before; return Err(err); }
            };
            els.push(el);
        }
        Ok(els)
    }
}
impl<'input, T: 'input, R: Rule<'input, [T]>> Rule<'input, [T]> for Consume<'input, [T], R> {
    type Output = Vec<R::Output>;
    
    fn parse_at<'cursor, 'this, 'index>(&'this self, input: &'cursor mut &'input [T], index: &'index mut usize) -> Result<Self::Output, ParseError> where 'input: 'this {
        let before = (*input, *index);
        let mut els = Vec::new();
        while !input.is_empty() {
            let el = match self.0.parse_at(input, index) {
                Ok(v) => v,
                Err(err) => { (*input, *index) = before; return Err(err); }
            };
            els.push(el);
        }
        Ok(els)
    }
}
#[derive(NamedRule)]
pub struct RepeatFor<'input, T: 'input + ?Sized, R: Rule<'input, T>, const REPETITIONS: usize>(pub R, pub(crate) PhantomData<&'input T>);
impl<'input, T: 'input + ?Sized, R: Rule<'input, T>, const REPETITIONS: usize> Rule<'input, T> for RepeatFor<'input, T, R, REPETITIONS> {
    type Output = [R::Output; REPETITIONS];
    
    fn parse_at<'cursor, 'this, 'index>(&'this self, input: &'cursor mut &'input T, index: &'index mut usize) -> Result<Self::Output, ParseError> where 'input: 'this {
        let before = (*input, *index);
        let mut arr: [Option<R::Output>; REPETITIONS] = [const { None }; REPETITIONS];
        for el in &mut arr {
            el.replace(match self.0.parse_at(input, index) {
                Ok(v) => v,
                Err(err) => {
                    (*input, *index) = before;
                    return Err(err);
                }
            });
        }
        Ok(arr.map(|v| v.unwrap()))
    }
}
#[derive(NamedRule)]
pub struct Repeat<'input, T: 'input + ?Sized, R: Rule<'input, T>>(pub R, pub usize, pub(crate) PhantomData<&'input T>);
impl<'input, T: 'input + ?Sized, R: Rule<'input, T>> Rule<'input, T> for Repeat<'input, T, R> {
    type Output = Vec<R::Output>;
    
    fn parse_at<'cursor, 'this, 'index>(&'this self, input: &'cursor mut &'input T, index: &'index mut usize) -> Result<Self::Output, ParseError> where 'input: 'this {
        let before = (*input, *index);
        let mut arr = Vec::with_capacity(self.1);
        for _ in 0..self.1 {
            arr.push(match self.0.parse_at(input, index) {
                Ok(v) => v,
                Err(err) => {
                    (*input, *index) = before;
                    return Err(err);
                }
            });
        }
        Ok(arr)
    }
}
#[derive(NamedRule)]
pub struct Many<'input, T: 'input + ?Sized, R: Rule<'input, T>> {
    rule: R,
    limit: Option<usize>,
    _p: PhantomData<&'input T>
}
impl<'input, T: 'input + ?Sized, R: Rule<'input, T>> Many<'input, T, R> {
    pub fn unlimited(rule: R) -> Self {
        Self { rule, limit: None, _p: PhantomData }
    }
    pub fn limited(rule: R, limit: usize) -> Self {
        Self { rule, limit: Some(limit), _p: PhantomData }
    }
}
impl<'input, T: 'input + ?Sized, R: Rule<'input, T>> Rule<'input, T> for Many<'input, T, R> {
    type Output = Vec<R::Output>;
    
    fn parse_at<'cursor, 'this, 'index>(&'this self, input: &'cursor mut &'input T, index: &'index mut usize) -> Result<Self::Output, ParseError> where 'input: 'this {
        let mut arr = Vec::new();
        let mut i = 0;
        while let Ok(res) = self.rule.parse_at(input, index) {
            arr.push(res);
            i += 1;
            if self.limit.is_some_and(|limit| limit >= i) {
                break;
            }
        }
        Ok(arr)
    }
}
#[derive(Debug, Copy, Clone, NamedRule)]
pub struct Any;
impl<'input, T: 'input> Rule<'input, [T]> for Any {
    type Output = &'input T;
    fn parse_at<'cursor, 'this, 'index>(&'this self, input: &'cursor mut &'input [T], index: &'index mut usize) -> Result<Self::Output, ParseError> where 'input: 'this {
        (!input.is_empty())
            .then(|| {
                let source = &input[0];
                *input = &input[1..];
                *index += 1;
                source
            })
            .ok_or(ParseError::new(Some(Box::new(UnexpectedEOF)), self.name(), *index))
    }
}
impl<'input> Rule<'input, str> for Any {
    type Output = char;
    fn parse_at<'cursor, 'this, 'index>(&'this self, input: &'cursor mut &'input str, index: &'index mut usize) -> Result<Self::Output, ParseError> where 'input: 'this {
        input.chars().next()
            .inspect(|chr| {
                let len = chr.len_utf8();
                *input = &input[len..];
                *index += len;
            })
            .ok_or(ParseError::new(Some(Box::new(UnexpectedEOF)), self.name(), *index))
    }
}
#[derive(Debug, Clone, PartialEq, NamedRule)]
pub struct While<F, T> { func: F, _p: PhantomData<T> }
impl<T, F: Fn(&T) -> bool> While<F, T> {
    pub fn from(func: F) -> Self {
        Self { func, _p: PhantomData }
    }
}
impl<'input, F: Fn(&char) -> bool> Rule<'input, str> for While<F, char> {
    type Output = &'input str;
    fn parse_at<'cursor, 'this, 'index>(&'this self, input: &'cursor mut &'input str, index: &'index mut usize)
        -> Result<Self::Output, ParseError> where 'input: 'this
    {
        let offset = input.find(|c: char| !(self.func)(&c))
            .unwrap_or(input.len());
        let res = &input[..offset];
        *input = &input[offset..];
        *index += offset;
        Ok(res)
    }
}
impl<'input, T: 'input, F: Fn(&T) -> bool> Rule<'input, [T]> for While<F, T> {
    type Output = &'input [T];
    fn parse_at<'cursor, 'this, 'index>(&'this self, input: &'cursor mut &'input [T], index: &'index mut usize)
        -> Result<Self::Output, ParseError> where 'input: 'this
    {
        let offset = (*input).iter().position(|c: &T| !(self.func)(c))
            .unwrap_or(input.len());
        let res = &input[..offset];
        *input = &input[offset..];
        *index += offset;
        Ok(res)
    }
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Span<'input, T: 'input + ?Sized, O> {
    pub span: Range<usize>,
    pub source: &'input T,
    pub output: O
}
#[derive(NamedRule)]
pub struct Spanned<'input, T: 'input + ?Sized, R: Rule<'input, T>> { pub(crate) rule: R, pub(crate) _p: PhantomData<&'input T> }
impl<'input, T: 'input + Index<RangeTo<usize>, Output = T> + ?Sized, R: Rule<'input, T>> Rule<'input, T> for Spanned<'input, T, R> {
    type Output = Span<'input, T, R::Output>;
    
    fn parse_at<'cursor, 'this, 'index>(&'this self, input: &'cursor mut &'input T, index: &'index mut usize) -> Result<Self::Output, ParseError> where 'input: 'this {
        let before = (*input, *index);
        let res = self.rule.parse_at(input, index)?;
        Ok(Span {
            span: before.1 .. *index,
            source: &before.0[..*index - before.1],
            output: res
        })
    }
}
#[derive(Debug, PartialEq, NamedRule)]
pub struct Fail<E: core::error::Error + Clone + 'static>(pub E);
impl<E: core::error::Error + Clone + 'static> Fail<E> {
    #[inline]
    pub fn new(err: E) -> Self {
        Self(err)
    }
}
impl<'input, T: ?Sized + 'input, E: core::error::Error + Clone + 'static> Rule<'input, T> for Fail<E> {
    type Output = crate::Never;
    fn parse_at<'cursor, 'this, 'index>(&'this self, _input: &'cursor mut &'input T, index: &'index mut usize)
        -> Result<Self::Output, ParseError> where 'input: 'this
    {
        Err(ParseError::new(Some(Box::new(self.0.clone())), self.name(), *index))
    }
}
pub type AnyRule<'rule, 'input, In, Out> = &'rule dyn Rule<'input, In, Output = Out>;