use crate::{
Colon, Comma, Cons, Delimited, Dot, EndOfStream, Error, Except, Expect, Nothing, Parse, Parser,
PathSep, RefineErr, Result, Semicolon, ToTokens, TokenIter, TokenStream,
};
use std::{cell::RefCell, marker::PhantomData, ops::Deref, rc::Rc};
impl<T: Parse> Parser for Option<T> {
fn parser(tokens: &mut TokenIter) -> Result<Self> {
match T::parse(tokens) {
Ok(value) => Ok(Some(value)),
Err(_) => Ok(None),
}
}
}
impl<T: ToTokens> ToTokens for Option<T> {
fn to_tokens(&self, tokens: &mut TokenStream) {
if let Some(t) = self.as_ref() {
t.to_tokens(tokens);
}
}
}
impl<T: Parse> Parser for Vec<T> {
fn parser(tokens: &mut TokenIter) -> Result<Self> {
let mut output = Vec::new();
let mut track_pos = tokens.counter();
while let Ok(value) = T::parse(tokens) {
if tokens.counter() == track_pos {
return Error::infinite_loop::<Vec<T>>(tokens.clone().next(), tokens);
}
track_pos = tokens.counter();
output.push(value);
}
Ok(output)
}
}
impl<T: ToTokens> ToTokens for Vec<T> {
fn to_tokens(&self, tokens: &mut TokenStream) {
for value in self {
value.to_tokens(tokens);
}
}
}
#[derive(Clone)]
pub struct NonEmptyOption<T>(pub Option<T>);
impl<T: Parse> Parser for NonEmptyOption<T> {
fn parser(tokens: &mut TokenIter) -> Result<Self> {
Ok(Self(<Option<Cons<Except<EndOfStream>, T>>>::parse_with(
tokens,
|t, _| Ok(t.map(|t| t.second)),
)?))
}
}
impl<T: ToTokens> ToTokens for NonEmptyOption<T> {
#[inline]
fn to_tokens(&self, tokens: &mut TokenStream) {
self.0.to_tokens(tokens);
}
}
#[mutants::skip]
impl<T: std::fmt::Debug> std::fmt::Debug for NonEmptyOption<T> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct(&format!("NonEmptyOption<{}>", std::any::type_name::<T>()))
.finish()
}
}
impl<T> std::ops::Deref for NonEmptyOption<T> {
type Target = Option<T>;
fn deref(&self) -> &Self::Target {
&self.0
}
}
#[allow(clippy::missing_errors_doc)]
pub trait RangedRepeats: Sized {
fn parse_repeats(tokens: &mut TokenIter, min: usize, max: usize) -> Result<Self>;
fn parse_any(tokens: &mut TokenIter) -> Result<Self> {
Self::parse_repeats(tokens, 0, usize::MAX)
}
fn parse_many(tokens: &mut TokenIter) -> Result<Self> {
Self::parse_repeats(tokens, 1, usize::MAX)
}
fn parse_optional(tokens: &mut TokenIter) -> Result<Self> {
Self::parse_repeats(tokens, 0, 1)
}
fn parse_exactly(tokens: &mut TokenIter, n: usize) -> Result<Self> {
Self::parse_repeats(tokens, n, n)
}
fn parse_at_most(tokens: &mut TokenIter, n: usize) -> Result<Self> {
Self::parse_repeats(tokens, 0, n)
}
fn parse_at_least(tokens: &mut TokenIter, n: usize) -> Result<Self> {
Self::parse_repeats(tokens, n, usize::MAX)
}
}
impl<T: Parse> RangedRepeats for Vec<T> {
fn parse_repeats(tokens: &mut TokenIter, min: usize, max: usize) -> Result<Self> {
let mut output = Vec::with_capacity(min);
let mut at = tokens.clone().next();
for _ in 0..max {
let pos_before = tokens.counter();
at = tokens.clone().next();
if let Ok(value) = T::parse(tokens) {
if tokens.counter() == pos_before {
return Error::infinite_loop::<Vec<T>>(at, tokens);
}
output.push(value);
} else {
break;
}
}
if output.len() >= min {
Ok(output)
} else {
Error::other(
at,
tokens,
format!("less than {} elements, got {}", min, output.len()),
)
}
}
}
impl<T: Parse> Parser for Box<T> {
fn parser(tokens: &mut TokenIter) -> Result<Self> {
Ok(Box::new(T::parser(tokens).refine_err::<Self>()?))
}
}
impl<T: ToTokens> ToTokens for Box<T> {
fn to_tokens(&self, tokens: &mut TokenStream) {
self.as_ref().to_tokens(tokens);
}
}
impl<T: Parse> Parser for Rc<T> {
fn parser(tokens: &mut TokenIter) -> Result<Self> {
Ok(Rc::new(T::parser(tokens).refine_err::<Self>()?))
}
}
impl<T: ToTokens> ToTokens for Rc<T> {
fn to_tokens(&self, tokens: &mut TokenStream) {
self.as_ref().to_tokens(tokens);
}
}
impl<T: Parse> Parser for RefCell<T> {
fn parser(tokens: &mut TokenIter) -> Result<Self> {
Ok(RefCell::new(T::parser(tokens).refine_err::<Self>()?))
}
}
impl<T: ToTokens> ToTokens for RefCell<T> {
fn to_tokens(&self, tokens: &mut TokenStream) {
self.borrow().to_tokens(tokens);
}
}
#[derive(Clone)]
pub struct LazyVec<T, S> {
pub vec: Vec<T>,
pub terminator: S,
}
impl<T: Parse, S: Parse> Parser for LazyVec<T, S> {
fn parser(tokens: &mut TokenIter) -> Result<Self> {
let mut vec = Vec::new();
loop {
if let Ok(terminator) = S::parse(tokens) {
return Ok(Self { vec, terminator });
}
let pos_before_t = tokens.counter();
let value = T::parse(tokens)?;
if tokens.counter() == pos_before_t {
return Error::infinite_loop::<LazyVec<T, S>>(tokens.clone().next(), tokens);
}
vec.push(value);
}
}
}
impl<T: ToTokens, S: ToTokens> ToTokens for LazyVec<T, S> {
fn to_tokens(&self, tokens: &mut TokenStream) {
self.vec.iter().for_each(|value| value.to_tokens(tokens));
self.terminator.to_tokens(tokens);
}
}
impl<T: Parse, S: Parse> RangedRepeats for LazyVec<T, S> {
fn parse_repeats(tokens: &mut TokenIter, min: usize, max: usize) -> Result<Self> {
let mut vec = Vec::with_capacity(min);
let mut at = tokens.clone().next();
for _ in 0..max {
at = tokens.clone().next();
if let Ok(terminator) = S::parse(tokens) {
return if vec.len() >= min {
Ok(Self { vec, terminator })
} else {
Error::other(
at,
tokens,
format!("less than {} elements, got {}", min, vec.len()),
)
};
}
let pos_before_t = tokens.counter();
let value = T::parse(tokens)?;
if tokens.counter() == pos_before_t {
return Error::infinite_loop::<LazyVec<T, S>>(at, tokens);
}
vec.push(value);
}
Error::other(at, tokens, format!("more than {max} elements"))
}
}
impl<T, S> IntoIterator for LazyVec<T, S> {
type Item = T;
type IntoIter = std::vec::IntoIter<Self::Item>;
fn into_iter(self) -> Self::IntoIter {
self.vec.into_iter()
}
}
#[mutants::skip]
impl<T: std::fmt::Debug, S: std::fmt::Debug> std::fmt::Debug for LazyVec<T, S> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct(&format!(
"LazyVec<{}, {}>",
std::any::type_name::<T>(),
std::any::type_name::<S>()
))
.field("vec", &self.vec)
.field("terminator", &self.terminator)
.finish()
}
}
#[derive(Clone)]
pub struct LazyVecUntil<T, S> {
pub vec: Vec<T>,
phantom: PhantomData<S>,
}
impl<T: Parse, S: Parse> Parser for LazyVecUntil<T, S> {
fn parser(tokens: &mut TokenIter) -> Result<Self> {
let mut vec = Vec::new();
loop {
if <Expect<S>>::parse(tokens).is_ok() {
return Ok(Self {
vec,
phantom: PhantomData,
});
}
let pos_before_t = tokens.counter();
let value = T::parse(tokens)?;
if tokens.counter() == pos_before_t {
return Error::infinite_loop::<LazyVecUntil<T, S>>(tokens.clone().next(), tokens);
}
vec.push(value);
}
}
}
impl<T: ToTokens, S: ToTokens> ToTokens for LazyVecUntil<T, S> {
fn to_tokens(&self, tokens: &mut TokenStream) {
self.vec.iter().for_each(|value| value.to_tokens(tokens));
}
}
impl<T: Parse, S: Parse> RangedRepeats for LazyVecUntil<T, S> {
fn parse_repeats(tokens: &mut TokenIter, min: usize, max: usize) -> Result<Self> {
let mut vec = Vec::with_capacity(min);
let mut at = tokens.clone().next();
for _ in 0..max {
at = tokens.clone().next();
if <Expect<S>>::parse(tokens).is_ok() {
return if vec.len() >= min {
Ok(Self {
vec,
phantom: PhantomData,
})
} else {
Error::other(
at,
tokens,
format!("less than {} elements, got {}", min, vec.len()),
)
};
}
let pos_before_t = tokens.counter();
let value = T::parse(tokens)?;
if tokens.counter() == pos_before_t {
return Error::infinite_loop::<LazyVecUntil<T, S>>(at, tokens);
}
vec.push(value);
}
Error::other(at, tokens, format!("more than {max} elements"))
}
}
impl<T, S> IntoIterator for LazyVecUntil<T, S> {
type Item = T;
type IntoIter = std::vec::IntoIter<Self::Item>;
fn into_iter(self) -> Self::IntoIter {
self.vec.into_iter()
}
}
#[mutants::skip]
impl<T: std::fmt::Debug, S: std::fmt::Debug> std::fmt::Debug for LazyVecUntil<T, S> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct(&format!(
"LazyVec<{}, {}>",
std::any::type_name::<T>(),
std::any::type_name::<S>()
))
.field("vec", &self.vec)
.finish()
}
}
#[allow(non_snake_case)]
pub mod TrailingDelimiter {
#[derive(Copy, Clone, Debug)]
pub struct Mandatory;
#[derive(Copy, Clone, Debug)]
pub struct Optional;
#[derive(Copy, Clone, Debug)]
pub struct Forbidden;
}
#[derive(Clone)]
pub struct DelimitedVec<
T,
D,
P = TrailingDelimiter::Optional,
const MIN: usize = 0,
const MAX: usize = { usize::MAX },
>(Vec<Delimited<T, D>>, PhantomData<P>);
impl<T: Parse, D: Parse, const MIN: usize, const MAX: usize> Parser
for DelimitedVec<T, D, TrailingDelimiter::Optional, MIN, MAX>
{
fn parser(tokens: &mut TokenIter) -> Result<Self> {
const { assert!(MIN <= MAX) };
let mut output = Vec::new();
let mut at = tokens.clone().next();
while output.len() < MAX {
let pos_before = tokens.counter();
if let Ok(delimited) = Delimited::<T, D>::parse(tokens) {
if tokens.counter() == pos_before {
return Error::infinite_loop::<
DelimitedVec<T, D, TrailingDelimiter::Optional, MIN, MAX>,
>(at, tokens);
}
at = tokens.clone().next();
let done = delimited.delimiter.is_none();
output.push(delimited);
if done {
break;
}
} else {
break;
}
}
#[allow(unused_comparisons)]
if output.len() >= MIN {
Ok(Self(output, PhantomData))
} else {
Error::other(
at,
tokens,
format!(
"Expected at least {MIN} elements in DelimitedVec<{}, {}, {MIN}, {MAX}, {:?}> but got only {}",
std::any::type_name::<T>(),
std::any::type_name::<D>(),
TrailingDelimiter::Optional,
output.len(),
),
)
}
}
}
impl<T: Parse + ToTokens, D: Parse, const MIN: usize, const MAX: usize> Parser
for DelimitedVec<T, D, TrailingDelimiter::Mandatory, MIN, MAX>
{
fn parser(tokens: &mut TokenIter) -> Result<Self> {
const { assert!(MIN <= MAX) };
let mut output = Vec::new();
let at = tokens.clone().next();
#[allow(unused_comparisons)]
while output.len() < MAX {
let pos_before = tokens.counter();
match Delimited::<T, D>::parse_with(tokens, |d, tokens| {
if d.delimiter.is_some() {
Ok(d)
} else {
Error::unexpected_token(d.value.to_token_iter().next(), tokens)
}
}) {
Ok(delimited) => {
if tokens.counter() == pos_before {
return Error::infinite_loop::<
DelimitedVec<T, D, TrailingDelimiter::Mandatory, MIN, MAX>,
>(at, tokens);
}
output.push(delimited);
}
Err(_) => break,
}
}
#[allow(unused_comparisons)]
if output.len() >= MIN {
Ok(Self(output, PhantomData))
} else {
Error::other(
at,
tokens,
format!(
"Expected at least {MIN} elements in DelimitedVec<{}, {}, {MIN}, {MAX}, {:?}> but got only {}",
std::any::type_name::<T>(),
std::any::type_name::<D>(),
TrailingDelimiter::Mandatory,
output.len(),
),
)
}
}
}
impl<T: Parse + ToTokens, D: Parse, const MIN: usize, const MAX: usize> Parser
for DelimitedVec<T, D, TrailingDelimiter::Forbidden, MIN, MAX>
{
fn parser(tokens: &mut TokenIter) -> Result<Self> {
const { assert!(MIN <= MAX) };
let mut output = Vec::new();
let at = tokens.clone().next();
while output.len() < MAX {
let pos_before = tokens.counter();
if let Ok(delimited) = Delimited::<T, D>::parse(tokens) {
if tokens.counter() == pos_before {
return Error::infinite_loop::<
DelimitedVec<T, D, TrailingDelimiter::Forbidden, MIN, MAX>,
>(at, tokens);
}
let done = delimited.delimiter.is_none();
output.push(delimited);
if done {
break;
}
} else {
break;
}
}
#[allow(unused_comparisons)]
if output.len() >= MIN {
if let Some(last) = output.last() {
if last.delimiter.is_some() {
return Error::unexpected_token::<Self>(tokens.clone().next(), tokens);
}
}
Ok(Self(output, PhantomData))
} else {
Error::other(
at,
tokens,
format!(
"Expected at least {MIN} elements in DelimitedVec<{}, {}, {MIN}, {MAX}, {:?}> but got only {}",
std::any::type_name::<T>(),
std::any::type_name::<D>(),
TrailingDelimiter::Forbidden,
output.len(),
),
)
}
}
}
impl<T, D, P, const MIN: usize, const MAX: usize> From<DelimitedVec<T, D, P, MIN, MAX>> for Vec<T> {
fn from(delimited_vec: DelimitedVec<T, D, P, MIN, MAX>) -> Self {
const { assert!(MIN <= MAX) };
delimited_vec
.0
.into_iter()
.map(|delimited| delimited.value)
.collect()
}
}
impl<T: ToTokens, D: ToTokens, P, const MIN: usize, const MAX: usize> ToTokens
for DelimitedVec<T, D, P, MIN, MAX>
{
fn to_tokens(&self, tokens: &mut TokenStream) {
self.0.iter().for_each(|value| value.to_tokens(tokens));
}
}
impl<T: Parse, D: Parse, const MIN: usize, const MAX: usize> RangedRepeats
for DelimitedVec<T, D, TrailingDelimiter::Optional, MIN, MAX>
{
fn parse_repeats(tokens: &mut TokenIter, min: usize, max: usize) -> Result<Self> {
const { assert!(MIN <= MAX) };
if min < MIN {
Error::out_of_range::<MIN, _>(min, tokens.clone().next(), tokens)?;
}
if max > MAX {
Error::out_of_range::<MAX, _>(max, tokens.clone().next(), tokens)?;
}
let mut output = Vec::with_capacity(min);
let mut at = tokens.clone().next();
for _ in 0..max {
at = tokens.clone().next();
if let Ok(delimited) = Delimited::<T, D>::parse(tokens) {
let done = delimited.delimiter.is_none();
output.push(delimited);
if done {
break;
}
} else {
break;
}
}
if output.len() >= min {
Ok(Self(output, PhantomData))
} else {
Error::other(
at,
tokens,
format!("less than {} elements, got {}", min, output.len()),
)
}
}
}
impl<T: Parse, D: Parse, const MIN: usize, const MAX: usize> RangedRepeats
for DelimitedVec<T, D, TrailingDelimiter::Mandatory, MIN, MAX>
{
fn parse_repeats(tokens: &mut TokenIter, min: usize, max: usize) -> Result<Self> {
const { assert!(MIN <= MAX) };
if min < MIN {
Error::out_of_range::<MIN, _>(min, tokens.clone().next(), tokens)?;
}
if max > MAX {
Error::out_of_range::<MAX, _>(max, tokens.clone().next(), tokens)?;
}
let mut output = Vec::with_capacity(min);
let mut at = tokens.clone().next();
for _ in 0..max {
at = tokens.clone().next();
if let Ok(delimited) = Delimited::<T, D>::parse(tokens) {
if delimited.delimiter.is_none() {
return Error::other(at, tokens, "missing mandatory delimiter".to_string());
}
output.push(delimited);
} else {
break;
}
}
if output.len() >= min {
Ok(Self(output, PhantomData))
} else {
Error::other(
at,
tokens,
format!("less than {} elements, got {}", min, output.len()),
)
}
}
}
impl<T: Parse + ToTokens, D: Parse, const MIN: usize, const MAX: usize> RangedRepeats
for DelimitedVec<T, D, TrailingDelimiter::Forbidden, MIN, MAX>
{
fn parse_repeats(tokens: &mut TokenIter, min: usize, max: usize) -> Result<Self> {
const { assert!(MIN <= MAX) };
if min < MIN {
Error::out_of_range::<MIN, _>(min, tokens.clone().next(), tokens)?;
}
if max > MAX {
Error::out_of_range::<MAX, _>(max, tokens.clone().next(), tokens)?;
}
let mut output = Vec::with_capacity(min);
let mut at = tokens.clone().next();
for _ in 0..max {
at = tokens.clone().next();
if let Ok(delimited) = Delimited::<T, D>::parse(tokens) {
let done = delimited.delimiter.is_none();
output.push(delimited);
if done {
break;
}
} else {
break;
}
}
if output.len() >= min {
if let Some(last) = output.last() {
if last.delimiter.is_some() {
Error::unexpected_token::<_>(last.value.to_token_iter().next(), tokens)?;
}
}
Ok(Self(output, PhantomData))
} else {
Error::other(
at,
tokens,
format!("less than {} elements, got {}", min, output.len()),
)
}
}
}
impl<T, D, const MIN: usize, P, const MAX: usize> IntoIterator for DelimitedVec<T, D, P, MIN, MAX> {
type Item = Delimited<T, D>;
type IntoIter = std::vec::IntoIter<Self::Item>;
fn into_iter(self) -> Self::IntoIter {
self.0.into_iter()
}
}
impl<T, D, P, const MIN: usize, const MAX: usize> Deref for DelimitedVec<T, D, P, MIN, MAX> {
type Target = Vec<Delimited<T, D>>;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl<T, D: Default, const MIN: usize, const MAX: usize> FromIterator<T>
for DelimitedVec<T, D, TrailingDelimiter::Mandatory, MIN, MAX>
{
fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {
let iter = iter.into_iter();
let mut v: Vec<Delimited<T, D>> = Vec::with_capacity(iter.size_hint().0);
for value in iter {
v.push(Delimited {
value,
delimiter: Some(D::default()),
});
}
Self(v, PhantomData)
}
}
impl<T, D, const MIN: usize, const MAX: usize>
From<DelimitedVec<T, D, TrailingDelimiter::Mandatory, MIN, MAX>>
for DelimitedVec<T, D, TrailingDelimiter::Optional, MIN, MAX>
{
fn from(input: DelimitedVec<T, D, TrailingDelimiter::Mandatory, MIN, MAX>) -> Self {
Self(input.0, PhantomData)
}
}
impl<T, D: Default, const MIN: usize, const MAX: usize> FromIterator<T>
for DelimitedVec<T, D, TrailingDelimiter::Forbidden, MIN, MAX>
{
fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {
let iter = iter.into_iter();
let mut v: Vec<Delimited<T, D>> = Vec::with_capacity(iter.size_hint().0);
for value in iter {
if let Some(last) = v.last_mut() {
last.delimiter = Some(D::default());
}
v.push(Delimited {
value,
delimiter: None,
});
}
Self(v, PhantomData)
}
}
impl<T, D, const MIN: usize, const MAX: usize>
From<DelimitedVec<T, D, TrailingDelimiter::Forbidden, MIN, MAX>>
for DelimitedVec<T, D, TrailingDelimiter::Optional, MIN, MAX>
{
fn from(input: DelimitedVec<T, D, TrailingDelimiter::Forbidden, MIN, MAX>) -> Self {
Self(input.0, PhantomData)
}
}
#[mutants::skip]
impl<
T: std::fmt::Debug,
D: std::fmt::Debug,
P: std::fmt::Debug,
const MIN: usize,
const MAX: usize,
> std::fmt::Debug for DelimitedVec<T, D, P, MIN, MAX>
{
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_tuple(&format!(
"DelimitedVec<{}, {}, {}, {MIN}, {MAX}>",
std::any::type_name::<T>(),
std::any::type_name::<D>(),
std::any::type_name::<P>()
))
.field(&self.0)
.finish()
}
}
pub type CommaDelimitedVec<
T,
P = TrailingDelimiter::Optional,
const MIN: usize = 0,
const MAX: usize = { usize::MAX },
> = DelimitedVec<T, Comma, P, MIN, MAX>;
pub type SemicolonDelimitedVec<
T,
P = TrailingDelimiter::Mandatory,
const MIN: usize = 0,
const MAX: usize = { usize::MAX },
> = DelimitedVec<T, Semicolon, P, MIN, MAX>;
pub type DotDelimitedVec<
T,
P = TrailingDelimiter::Optional,
const MIN: usize = 0,
const MAX: usize = { usize::MAX },
> = DelimitedVec<T, Dot, P, MIN, MAX>;
pub type ColonDelimitedVec<
T,
P = TrailingDelimiter::Optional,
const MIN: usize = 0,
const MAX: usize = { usize::MAX },
> = DelimitedVec<T, Colon, P, MIN, MAX>;
pub type PathSepDelimitedVec<
T,
P = TrailingDelimiter::Forbidden,
const MIN: usize = 0,
const MAX: usize = { usize::MAX },
> = DelimitedVec<T, PathSep, P, MIN, MAX>;
pub type Repeats<
const MIN: usize,
const MAX: usize,
T,
D = Nothing,
P = TrailingDelimiter::Optional,
> = DelimitedVec<T, D, P, MIN, MAX>;
pub type Any<T, D = Nothing, P = TrailingDelimiter::Optional> = Repeats<0, { usize::MAX }, T, D, P>;
pub type Many<T, D = Nothing, P = TrailingDelimiter::Optional> =
Repeats<1, { usize::MAX }, T, D, P>;
pub type Optional<T, D = Nothing, P = TrailingDelimiter::Optional> = Repeats<0, 1, T, D, P>;
pub type Exactly<const N: usize, T, D = Nothing, P = TrailingDelimiter::Optional> =
Repeats<N, N, T, D, P>;
pub type AtMost<const N: usize, T, D = Nothing, P = TrailingDelimiter::Optional> =
Repeats<0, N, T, D, P>;
pub type AtLeast<const N: usize, T, D = Nothing, P = TrailingDelimiter::Optional> =
Repeats<N, { usize::MAX }, T, D, P>;