use core::fmt;
use core::ops::Bound::*;
use core::ops::{BitAnd, BitOr, BitXor, Mul, Not, RangeBounds, Rem, Shl, Shr, Sub};
use alloc::string::{String, ToString};
use alloc::sync::Arc;
use alloc::vec::Vec;
#[derive(Clone, PartialEq)]
pub struct Error {
actual: String,
expected: String,
remaining_input: String,
}
impl Error {
pub fn new<T>(
actual: impl ToString,
expected: impl ToString,
remaining_input: impl ToString,
) -> Result<T, Self> {
Err(Self {
actual: actual.to_string(),
expected: expected.to_string(),
remaining_input: remaining_input.to_string(),
})
}
}
impl fmt::Debug for Error {
fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
write!(
f,
"Expected `{}` but found `{}` when parsing `{}`",
self.expected,
self.actual,
self.remaining_input.replace("\n", "")
)
}
}
pub type Output<T> = Result<(T, String), Error>;
#[derive(Clone)]
pub struct Parser<T> {
parser: Arc<dyn Fn(&str) -> Output<T>>,
pub expectation: String,
}
impl<T> Parser<T>
where
T: 'static + Clone,
{
pub fn new(parser: impl Fn(&str) -> Output<T> + 'static, expectation: impl ToString) -> Self {
Self {
parser: Arc::new(parser),
expectation: expectation.to_string(),
}
}
pub fn expects(mut self, expectation: impl ToString) -> Self {
self.expectation = expectation.to_string();
self
}
pub fn parse(&self, input: &str) -> Result<T, Error> {
match self.parse_internal(input) {
Ok(t) => Ok(t.0),
Err(e) => Error::new(e.actual, self.expectation.clone(), e.remaining_input),
}
}
pub fn parse_internal(&self, input: &str) -> Output<T> {
(self.parser)(input)
}
pub fn map<O>(self, map_fn: fn(T) -> O) -> Parser<O>
where
O: 'static + Clone,
{
let expect = self.expectation.clone();
Parser::new(
move |s: &str| match self.parse_internal(s) {
Ok((first_out, input)) => Ok((map_fn(first_out), input)),
Err(e) => Err(e),
},
expect,
)
}
pub fn convert<O, E>(self, convert_fn: fn(T) -> Result<O, E>) -> Parser<O>
where
O: 'static + Clone,
E: 'static,
{
let expect = self.expectation.clone();
Parser::new(
move |s: &str| match self.parse_internal(s) {
Ok((first_out, input)) => {
let result = match convert_fn(first_out) {
Ok(value) => value,
Err(_) => return Error::new(s.clone(), "A convertible value", s.clone()),
};
Ok((result, input))
}
Err(e) => Err(e),
},
expect,
)
}
pub fn prefixes<O>(self, operand: Parser<O>) -> Parser<O>
where
O: 'static + Clone,
{
let expect = self.expectation.clone() + " followed by " + &operand.expectation.clone();
Parser::new(
move |s: &str| {
let (_, remaining) = self.parse_internal(s)?;
let (consumed, remaining) = operand.parse_internal(&remaining)?;
Ok((consumed, remaining))
},
expect,
)
}
pub fn suffix<O>(self, operand: Parser<O>) -> Parser<T>
where
O: 'static + Clone,
{
let expect = self.expectation.clone() + " followed by " + &operand.expectation.clone();
Parser::new(
move |s: &str| {
let (consumed, remaining) = self.parse_internal(s)?;
let (_, remaining) = operand.parse_internal(&remaining)?;
Ok((consumed, remaining))
},
expect,
)
}
pub fn is(self) -> Parser<()> {
let expect = self.expectation.clone();
Parser::new(
move |s: &str| match self.parse_internal(s) {
Ok(_) => Ok(((), s.to_string())),
Err(_) => Error::new(s, format!("Not {}", s), s),
},
expect,
)
}
pub fn isnt(self) -> Parser<()> {
let expect = self.expectation.clone();
Parser::new(
move |s: &str| match self.parse_internal(s) {
Ok(_) => Error::new(s, format!("Not {}", self.expectation), s),
Err(_) => Ok(((), s.to_string())),
},
format!("Not {}", expect),
)
}
pub fn and<O>(self, operand: Parser<O>) -> Parser<(T, O)>
where
O: 'static + Clone,
{
let expect = self.expectation.clone() + " and " + &operand.expectation.clone();
Parser::new(
move |s: &str| {
let (first_consumed, remaining) = self.parse_internal(s)?;
let (second_consumed, remaining) = operand.parse_internal(&remaining)?;
Ok(((first_consumed, second_consumed), remaining))
},
expect,
)
}
pub fn or(self, operand: Self) -> Self {
let expect = self.expectation.clone() + " or " + &operand.expectation.clone();
Parser::new(
move |s: &str| match self.parse_internal(s) {
Ok(t) => Ok(t),
Err(_) => operand.parse_internal(s),
},
expect,
)
}
pub fn repeat(self, range: impl RangeBounds<usize>) -> Parser<Vec<T>> {
let upper_bound: usize = match range.end_bound() {
Unbounded => core::usize::MAX,
Excluded(n) => *n,
Included(n) => *n,
};
let lower_bound: usize = match range.start_bound() {
Unbounded => 0,
Excluded(n) => *n,
Included(n) => *n,
};
let expect = self.expectation.clone()
+ &format!(" {:?}..{:?} times", range.start_bound(), range.end_bound());
Parser::new(
move |s: &str| {
let mut remaining_input = s.to_string();
let mut accum = vec![];
for n in 0..upper_bound {
match self.parse_internal(&remaining_input) {
Ok((consumed, unconsumed)) => {
accum.push(consumed);
remaining_input = unconsumed;
}
Err(e) => {
if n < lower_bound {
return Err(e);
} else {
return Ok((accum, remaining_input));
}
}
}
}
Ok((accum, remaining_input))
},
expect,
)
}
}
impl<T: 'static + Clone, S: ToString> Rem<S> for Parser<T> {
type Output = Self;
fn rem(self, rhs: S) -> Self::Output {
self.expects(rhs)
}
}
impl<T: 'static + Clone> BitOr for Parser<T> {
type Output = Parser<T>;
fn bitor(self, rhs: Self) -> Self::Output {
self.or(rhs)
}
}
impl<A: 'static + Clone, B: 'static + Clone> BitAnd<Parser<B>> for Parser<A> {
type Output = Parser<(A, B)>;
fn bitand(self, rhs: Parser<B>) -> Self::Output {
self.and(rhs)
}
}
impl<T: 'static + Clone> Not for Parser<T> {
type Output = Parser<()>;
fn not(self) -> Self::Output {
self.isnt()
}
}
impl<A: 'static + Clone, B: 'static + Clone> Shl<Parser<B>> for Parser<A> {
type Output = Parser<A>;
fn shl(self, rhs: Parser<B>) -> Self::Output {
self.suffix(rhs)
}
}
impl<A: 'static + Clone, B: 'static + Clone> Shr<Parser<B>> for Parser<A> {
type Output = Parser<B>;
fn shr(self, rhs: Parser<B>) -> Self::Output {
self.prefixes(rhs)
}
}
impl<T: 'static + Clone, R: RangeBounds<usize>> Mul<R> for Parser<T> {
type Output = Parser<Vec<T>>;
fn mul(self, rhs: R) -> Self::Output {
self.repeat(rhs)
}
}
impl<O, T> Sub<fn(T) -> O> for Parser<T>
where
O: 'static + Clone,
T: 'static + Clone,
{
type Output = Parser<O>;
fn sub(self, rhs: fn(T) -> O) -> Self::Output {
self.map(rhs)
}
}
impl<O, T, E> BitXor<fn(T) -> Result<O, E>> for Parser<T>
where
O: 'static + Clone,
T: 'static + Clone,
E: 'static,
{
type Output = Parser<O>;
fn bitxor(self, rhs: fn(T) -> Result<O, E>) -> Self::Output {
self.convert(rhs)
}
}