use std::{error::Error, ops::RangeBounds};
use crate::{sequence::Sequence, Parser, ParserError, ParserType};
pub struct ItemSeqParser;
impl<'a, Item: PartialEq, I, E> Parser<'a, I, Item, E, ItemSeqParser> for Item
where
I: ?Sized + Sequence<Item = Item>,
E: ParserError,
{
fn fab(&self, input: &mut &'a I) -> Result<Item, E> {
if let Some((start, rest)) = input.try_split_front() {
if start == *self {
*input = rest;
Ok(start)
} else {
Err(E::from_parser_error(*input, ParserType::Tag))
}
} else {
Err(E::from_parser_error(*input, ParserType::Tag))
}
}
}
pub struct SeqSeqParser;
impl<'a, I, E> Parser<'a, I, &'a I, E, SeqSeqParser> for &I
where
I: ?Sized + Sequence + PartialEq,
E: ParserError,
{
fn fab(&self, input: &mut &'a I) -> Result<&'a I, E> {
if let Some((start, rest)) = input.try_split_at(self.len()) {
if start == *self {
*input = rest;
Ok(start)
} else {
Err(E::from_parser_error(*input, ParserType::Tag))
}
} else {
Err(E::from_parser_error(*input, ParserType::Tag))
}
}
}
pub struct ConstArrayParser;
impl<'a, E, Item, const N: usize> Parser<'a, [Item], &'a [Item], E, ConstArrayParser> for [Item; N]
where
E: ParserError,
Item: Clone + PartialEq,
{
fn fab(&self, input: &mut &'a [Item]) -> Result<&'a [Item], E> {
self.as_slice().fab(input)
}
}
pub struct FnBoolSeqParser;
impl<'a, I, F, E, Item> Parser<'a, I, Item, E, FnBoolSeqParser> for F
where
I: ?Sized + Sequence<Item = Item>,
F: Fn(Item) -> bool,
E: ParserError,
Item: Clone,
{
fn fab(&self, input: &mut &'a I) -> Result<Item, E> {
if let Some((first, rest)) = input.try_split_front() {
if self(first.clone()) {
*input = rest;
Ok(first)
} else {
Err(E::from_parser_error(*input, ParserType::Tag))
}
} else {
Err(E::from_parser_error(*input, ParserType::Tag))
}
}
}
pub struct FnBoolRefSeqParser;
impl<'a, I, F, E, Item> Parser<'a, I, Item, E, FnBoolRefSeqParser> for F
where
I: ?Sized + Sequence<Item = Item>,
F: Fn(&Item) -> bool,
E: ParserError,
Item: Clone,
{
fn fab(&self, input: &mut &'a I) -> Result<Item, E> {
if let Some((first, rest)) = input.try_split_front() {
if self(&first) {
*input = rest;
Ok(first)
} else {
Err(E::from_parser_error(*input, ParserType::Tag))
}
} else {
Err(E::from_parser_error(*input, ParserType::Tag))
}
}
}
pub struct FnOptionSeqParser;
impl<'a, I, F, E, Item, FnOut> Parser<'a, I, FnOut, E, FnOptionSeqParser> for F
where
I: ?Sized + Sequence<Item = Item>,
F: Fn(Item) -> Option<FnOut>,
E: ParserError,
Item: Clone,
{
fn fab(&self, input: &mut &'a I) -> Result<FnOut, E> {
if let Some((first, rest)) = input.try_split_front() {
if let Some(out) = self(first) {
*input = rest;
Ok(out)
} else {
Err(E::from_parser_error(*input, ParserType::Tag))
}
} else {
Err(E::from_parser_error(*input, ParserType::Tag))
}
}
}
pub struct FnOptionRefSeqParser;
impl<'a, I, F, E, Item, FnOut> Parser<'a, I, FnOut, E, FnOptionRefSeqParser> for F
where
I: ?Sized + Sequence<Item = Item>,
F: Fn(&Item) -> Option<FnOut>,
E: ParserError,
Item: Clone,
{
fn fab(&self, input: &mut &'a I) -> Result<FnOut, E> {
if let Some((first, rest)) = input.try_split_front() {
if let Some(out) = self(&first) {
*input = rest;
Ok(out)
} else {
Err(E::from_parser_error(*input, ParserType::Tag))
}
} else {
Err(E::from_parser_error(*input, ParserType::Tag))
}
}
}
pub struct FnResultSeqParser;
impl<'a, I, F, E, Item, FnOut, FnErr> Parser<'a, I, FnOut, E, FnResultSeqParser> for F
where
I: ?Sized + Sequence<Item = Item>,
F: Fn(Item) -> Result<FnOut, FnErr>,
E: ParserError,
Item: Clone,
FnErr: 'static + Error + Send + Sync,
{
fn fab(&self, input: &mut &'a I) -> Result<FnOut, E> {
if let Some((first, rest)) = input.try_split_front() {
match self(first) {
Ok(out) => {
*input = rest;
Ok(out)
}
Err(err) => Err(E::from_external_error(*input, ParserType::Tag, err)),
}
} else {
Err(E::from_parser_error(*input, ParserType::Tag))
}
}
}
pub struct FnResultRefSeqParser;
impl<'a, I, F, E, Item, FnOut, FnErr> Parser<'a, I, FnOut, E, FnResultRefSeqParser> for F
where
I: ?Sized + Sequence<Item = Item>,
F: Fn(&Item) -> Result<FnOut, FnErr>,
E: ParserError,
Item: Clone,
FnErr: 'static + Error + Send + Sync,
{
fn fab(&self, input: &mut &'a I) -> Result<FnOut, E> {
if let Some((first, rest)) = input.try_split_front() {
match self(&first) {
Ok(out) => {
*input = rest;
Ok(out)
}
Err(err) => Err(E::from_external_error(*input, ParserType::Tag, err)),
}
} else {
Err(E::from_parser_error(*input, ParserType::Tag))
}
}
}
pub struct RangeSeqParser;
impl<'a, Item, I, E, R> Parser<'a, I, Item, E, RangeSeqParser> for R
where
I: ?Sized + Sequence<Item = Item>,
E: ParserError,
R: RangeBounds<Item>,
Item: PartialOrd,
{
fn fab(&self, input: &mut &'a I) -> Result<Item, E> {
if let Some((start, rest)) = input.try_split_front() {
if self.contains(&start) {
*input = rest;
Ok(start)
} else {
Err(E::from_parser_error(*input, ParserType::Tag))
}
} else {
Err(E::from_parser_error(*input, ParserType::Tag))
}
}
}
pub struct Take(pub usize);
impl<'a, I, E: ParserError> Parser<'a, I, &'a I, E, Take> for Take
where
I: ?Sized + Sequence,
{
fn fab(&self, input: &mut &'a I) -> Result<&'a I, E> {
let orig = *input;
let orig_len: usize = input.len();
for _ in 0..self.0 {
if let Some((_first, rest)) = input.try_split_front() {
*input = rest;
} else {
*input = orig;
return Err(E::from_parser_error(*input, ParserType::Tag));
}
}
let pos = orig_len - input.len();
*input = orig;
let (res, rest) = input
.try_split_at(pos)
.expect("Something went wrong in the take parser");
*input = rest;
Ok(res)
}
}
pub struct ParserFunction;
impl<'c, I: ?Sized + Sequence, O, E: ParserError, F> Parser<'c, I, O, E, ParserFunction> for F
where
F: Fn(&mut &'c I) -> Result<O, E>,
{
fn fab(&self, input: &mut &'c I) -> Result<O, E> {
let checkpoint = *input;
self(input).map_err(|mut err| {
*input = checkpoint;
err.add_context(checkpoint, ParserType::Function);
err
})
}
}