use crate::{
Error, IntoTokens, Match, Span, ToTokenStream, ToTokens, TokenStreamExt, TokenTree,
TokenTreeExt,
};
use std::{
borrow::{Borrow, BorrowMut, Cow},
marker::PhantomData,
mem::transmute,
ops::{
Deref, DerefMut, Index, IndexMut, Range, RangeFrom, RangeFull, RangeInclusive, RangeTo,
RangeToInclusive,
},
slice,
};
pub trait Parse<T: TokenTreeExt>:
Sized + DefaultParser<T, Parser = DefaultParserImpl<T, Self>>
{
fn parse(buf: &mut &TokenBuf<T>) -> Result<Self, Error<T::Span>>;
#[inline]
fn parse_all(buf: &mut &TokenBuf<T>) -> Result<Self, Error<T::Span>> {
Self::parser().parse_all(buf)
}
}
impl<T: TokenTreeExt, const LENGTH: usize> Parse<T> for [T; LENGTH] {
#[inline]
fn parse(buf: &mut &TokenBuf<T>) -> Result<Self, Error<T::Span>> {
if buf.len() >= LENGTH {
let parsed = buf[..LENGTH]
.into_iter()
.cloned()
.collect::<Vec<T>>()
.try_into()
.unwrap();
*buf = &buf[LENGTH..];
Ok(parsed)
} else {
Err(buf.error("no match"))
}
}
}
impl<T: TokenTreeExt, const LENGTH: usize> Parse<T> for Box<[T; LENGTH]> {
#[inline]
fn parse(buf: &mut &TokenBuf<T>) -> Result<Self, Error<T::Span>> {
if buf.len() >= LENGTH {
let parsed = buf[..LENGTH]
.into_iter()
.cloned()
.collect::<Vec<T>>()
.try_into()
.unwrap();
*buf = &buf[LENGTH..];
Ok(parsed)
} else {
Err(buf.error("no match"))
}
}
}
impl<T: TokenTreeExt, X: Parse<T>> Parse<T> for Option<X> {
#[inline]
fn parse(buf: &mut &TokenBuf<T>) -> Result<Self, Error<T::Span>> {
Ok(X::parse(buf).ok())
}
}
impl<T: TokenTreeExt, X: Parse<T>> Parse<T> for Vec<X> {
#[inline]
fn parse(buf: &mut &TokenBuf<T>) -> Result<Self, Error<T::Span>> {
let mut vec = Vec::new();
while let Ok(item) = X::parse(buf) {
vec.push(item);
}
if vec.is_empty() {
Err(buf.error("no match"))
} else {
Ok(vec)
}
}
}
pub trait Parser<T: TokenTreeExt> {
type Output<'p, 'b>
where
Self: 'p;
fn parse<'p, 'b>(
&'p self,
buf: &mut &'b TokenBuf<T>,
) -> Result<Self::Output<'p, 'b>, Error<T::Span>>;
#[inline]
fn parse_all<'p, 'b>(
&'p self,
buf: &mut &'b TokenBuf<T>,
) -> Result<Self::Output<'p, 'b>, Error<T::Span>> {
match self.parse(buf) {
Ok(result) if buf.is_empty() => Ok(result),
Err(e) => Err(e),
_ => Err(buf.error("unexpected tokens after input")),
}
}
#[inline]
fn optional(self) -> Optional<Self>
where
Self: Sized,
{
Optional(self)
}
}
impl<T: TokenTreeExt, X: Parser<T>> Parser<T> for [X] {
type Output<'p, 'b> = Vec<X::Output<'p, 'b>> where Self: 'p;
#[inline]
fn parse<'p, 'b>(
&'p self,
buf: &mut &'b TokenBuf<T>,
) -> Result<Self::Output<'p, 'b>, Error<T::Span>> {
self.iter().map(|x| x.parse(buf)).collect()
}
}
pub trait DefaultParser<T: TokenTreeExt> {
type Parser: Parser<T> + Copy + Default;
#[inline(always)]
fn parser() -> Self::Parser {
Self::Parser::default()
}
}
impl<T: TokenTreeExt, X: Parse<T>> DefaultParser<T> for X {
type Parser = DefaultParserImpl<T, X>;
}
#[repr(transparent)]
pub struct Optional<T>(pub T);
impl<T: TokenTreeExt, X: Parser<T>> Parser<T> for Optional<X> {
type Output<'p, 'b> = Option<X::Output<'p, 'b>> where Self: 'p;
#[inline]
fn parse<'p, 'b>(
&'p self,
buf: &mut &'b TokenBuf<T>,
) -> Result<Self::Output<'p, 'b>, Error<T::Span>> {
Ok(self.0.parse(buf).ok())
}
}
pub struct DefaultParserImpl<T: TokenTreeExt, X: Parse<T>>(PhantomData<fn() -> (T, X)>);
impl<T: TokenTreeExt, X: Parse<T>> Clone for DefaultParserImpl<T, X> {
#[inline(always)]
fn clone(&self) -> Self {
*self
}
}
impl<T: TokenTreeExt, X: Parse<T>> Copy for DefaultParserImpl<T, X> {}
impl<T: TokenTreeExt, X: Parse<T>> Default for DefaultParserImpl<T, X> {
#[inline(always)]
fn default() -> Self {
Self(PhantomData)
}
}
impl<T: TokenTreeExt, X: Parse<T>> Parser<T> for DefaultParserImpl<T, X> {
type Output<'p, 'b> = X where Self: 'p;
#[inline]
fn parse<'p, 'b>(
&'p self,
buf: &mut &'b TokenBuf<T>,
) -> Result<Self::Output<'p, 'b>, Error<T::Span>> {
X::parse(buf)
}
}
pub trait ToTokenBuffer<T: TokenTree> {
fn extend_token_buffer(&self, token_buffer: &mut TokenBuffer<T>);
#[inline]
fn to_token_buffer(&self) -> TokenBuffer<T> {
let mut tb = TokenBuffer::new();
self.extend_token_buffer(&mut tb);
tb
}
}
impl<T: TokenTree, X: IntoTokens<T> + Clone> ToTokenBuffer<T> for X {
#[inline]
fn extend_token_buffer(&self, token_buffer: &mut TokenBuffer<T>) {
token_buffer.0.extend(self.to_tokens())
}
}
pub trait AsTokenBuf<'a, T: TokenTree> {
fn as_token_buf(&'a self) -> &'a TokenBuf<T>;
}
impl<'a, T: TokenTree, X: 'a> AsTokenBuf<'a, T> for X
where
&'a X: Into<&'a TokenBuf<T>>,
{
#[inline]
fn as_token_buf(&'a self) -> &'a TokenBuf<T> {
self.into()
}
}
pub trait AsTokenBufMut<'a, T: TokenTree> {
fn as_token_buf_mut(&'a mut self) -> &'a mut TokenBuf<T>;
}
impl<'a, T: TokenTree, X: 'a> AsTokenBufMut<'a, T> for X
where
&'a mut X: Into<&'a mut TokenBuf<T>>,
{
#[inline]
fn as_token_buf_mut(&'a mut self) -> &'a mut TokenBuf<T> {
self.into()
}
}
#[derive(Clone, Debug, Default)]
pub struct TokenBuffer<T: TokenTree>(Vec<T>);
impl<T: TokenTreeExt> TokenBuffer<T> {
#[inline]
pub fn as_buf(&self) -> &TokenBuf<T> {
self
}
#[inline]
pub fn as_buf_mut(&mut self) -> &mut TokenBuf<T> {
self
}
#[inline]
pub fn parse_all<P: Parse<T>>(&self) -> Result<P, Error<T::Span>> {
self.as_buf().parse_all() }
}
impl<T: TokenTree> TokenBuffer<T> {
#[inline]
pub const fn new() -> Self {
Self(Vec::new())
}
}
impl<T: TokenTreeExt> AsRef<TokenBuf<T>> for TokenBuffer<T> {
#[inline]
fn as_ref(&self) -> &TokenBuf<T> {
self.as_buf()
}
}
impl<T: TokenTreeExt> AsMut<TokenBuf<T>> for TokenBuffer<T> {
#[inline]
fn as_mut(&mut self) -> &mut TokenBuf<T> {
self.as_buf_mut()
}
}
impl<T: TokenTreeExt> Borrow<TokenBuf<T>> for TokenBuffer<T> {
#[inline]
fn borrow(&self) -> &TokenBuf<T> {
self.as_buf()
}
}
impl<T: TokenTreeExt> BorrowMut<TokenBuf<T>> for TokenBuffer<T> {
#[inline]
fn borrow_mut(&mut self) -> &mut TokenBuf<T> {
self.as_buf_mut()
}
}
impl<T: TokenTreeExt> Deref for TokenBuffer<T> {
type Target = TokenBuf<T>;
#[inline]
fn deref(&self) -> &Self::Target {
TokenBuf::from_ref(&self.0[..])
}
}
impl<T: TokenTreeExt> DerefMut for TokenBuffer<T> {
#[inline]
fn deref_mut(&mut self) -> &mut Self::Target {
TokenBuf::from_mut(&mut self.0[..])
}
}
impl<T: TokenTree, X: ToTokenBuffer<T>> Extend<X> for TokenBuffer<T> {
#[inline]
fn extend<I: IntoIterator<Item = X>>(&mut self, iter: I) {
for i in iter {
i.extend_token_buffer(self);
}
}
}
#[cfg(feature = "proc-macro")]
impl From<proc_macro::TokenStream> for TokenBuffer<proc_macro::TokenTree> {
#[inline]
fn from(value: proc_macro::TokenStream) -> Self {
Self::from_iter(value)
}
}
#[cfg(feature = "proc-macro2")]
impl From<proc_macro2::TokenStream> for TokenBuffer<proc_macro2::TokenTree> {
#[inline]
fn from(value: proc_macro2::TokenStream) -> Self {
Self::from_iter(value)
}
}
#[cfg(feature = "proc-macro")]
impl From<TokenBuffer<proc_macro::TokenTree>> for proc_macro::TokenStream {
#[inline]
fn from(value: TokenBuffer<proc_macro::TokenTree>) -> Self {
value.to_token_stream()
}
}
#[cfg(feature = "proc-macro2")]
impl From<TokenBuffer<proc_macro2::TokenTree>> for proc_macro2::TokenStream {
#[inline]
fn from(value: TokenBuffer<proc_macro2::TokenTree>) -> Self {
value.to_token_stream()
}
}
impl<T: TokenTree> From<TokenBuffer<T>> for Box<[T]> {
#[inline]
fn from(value: TokenBuffer<T>) -> Self {
value.0.into()
}
}
impl<T: TokenTree> From<TokenBuffer<T>> for Vec<T> {
#[inline]
fn from(value: TokenBuffer<T>) -> Self {
value.0
}
}
impl<T: TokenTree> From<Vec<T>> for TokenBuffer<T> {
#[inline]
fn from(value: Vec<T>) -> Self {
Self(value)
}
}
impl<T: TokenTree, X: ToTokenBuffer<T>> FromIterator<X> for TokenBuffer<T> {
#[inline]
fn from_iter<I: IntoIterator<Item = X>>(iter: I) -> Self {
let mut buf = TokenBuffer::new();
for i in iter {
i.extend_token_buffer(&mut buf);
}
buf
}
}
impl<T: TokenTree, I: TokenBufferIndex<T>> Index<I> for TokenBuffer<T> {
type Output = I::Output;
#[inline]
fn index(&self, index: I) -> &Self::Output {
index.index(&self.0)
}
}
impl<T: TokenTree, I: TokenBufferIndex<T>> IndexMut<I> for TokenBuffer<T> {
#[inline]
fn index_mut(&mut self, index: I) -> &mut Self::Output {
index.index_mut(&mut self.0)
}
}
impl<T: TokenTree> IntoIterator for TokenBuffer<T> {
type IntoIter = <Vec<T> as IntoIterator>::IntoIter;
type Item = T;
#[inline]
fn into_iter(self) -> Self::IntoIter {
self.0.into_iter()
}
}
impl<T: TokenTree> IntoTokens<T> for TokenBuffer<T> {
#[inline]
fn into_tokens(self) -> impl Iterator<Item = T>
where
Self: Sized,
{
self.0.into_iter()
}
}
impl<T: TokenTree, const LENGTH: usize> TryFrom<TokenBuffer<T>> for [T; LENGTH] {
type Error = <Self as TryFrom<Vec<T>>>::Error;
#[inline]
fn try_from(value: TokenBuffer<T>) -> Result<Self, Self::Error> {
value.0.try_into()
}
}
#[derive(Debug)]
#[repr(transparent)]
pub struct TokenBuf<T: TokenTree>([T]);
impl<T: TokenTreeExt> TokenBuf<T> {
#[inline]
fn from_ref(r: &[T]) -> &Self {
unsafe {
transmute::<&[T], &Self>(r)
}
}
#[inline]
fn from_mut(r: &mut [T]) -> &mut Self {
unsafe {
transmute::<&mut [T], &mut Self>(r)
}
}
#[inline]
pub fn error(&self, message: impl Into<Cow<'static, str>>) -> Error<T::Span> {
Error::with_span(
self.0
.first()
.map(|t| t.span())
.unwrap_or_else(T::Span::call_site),
message,
)
}
#[inline]
pub fn parse<P: Parse<T>>(self: &mut &Self) -> Result<P, Error<T::Span>> {
P::parse(self)
}
#[inline]
pub fn parse_all<P: Parse<T>>(self: &mut &Self) -> Result<P, Error<T::Span>> {
P::parse_all(self)
}
#[inline]
pub fn parse_prefix<'a, M: 'a>(
self: &mut &'a Self,
mut match_fn: impl FnMut(&T) -> Match<M>,
) -> Result<M, Error<T::Span>> {
self.parse_prefix_buf(|_, token, _| match_fn(token))
}
#[inline]
pub fn parse_prefix_next<'a, M: 'a>(
self: &mut &'a Self,
mut match_fn: impl FnMut(&T, Option<&T>) -> Match<M>,
) -> Result<M, Error<T::Span>> {
self.parse_prefix_buf(|_, token, next| match_fn(token, next))
}
#[inline]
pub fn parse_prefix_buf<'a, M: 'a>(
self: &mut &'a Self,
mut match_fn: impl FnMut(&'a Self, &T, Option<&T>) -> Match<M>,
) -> Result<M, Error<T::Span>> {
let mut result = None;
for i in 1..=self.len() {
match match_fn(&self[..i], &self[i - 1], self.get(i)) {
Match::Complete(m) => {
*self = &self[i..];
return Ok(m);
}
Match::Partial(m) => result = Some((m, &self[i..])),
Match::NeedMore => (),
Match::NoMatch => break,
}
}
result
.ok_or_else(|| self.error("no match"))
.map(|(result, rest)| {
*self = rest;
result
})
}
#[inline]
pub fn parse_suffix<'a, M: 'a>(
self: &mut &'a Self,
mut match_fn: impl FnMut(&T) -> Match<M>,
) -> Result<M, Error<T::Span>> {
self.parse_suffix_buf(|_, token, _| match_fn(token))
}
#[inline]
pub fn parse_suffix_next<'a, M: 'a>(
self: &mut &'a Self,
mut match_fn: impl FnMut(&T, Option<&T>) -> Match<M>,
) -> Result<M, Error<T::Span>> {
self.parse_suffix_buf(|_, token, next| match_fn(token, next))
}
#[inline]
pub fn parse_suffix_buf<'a, M: 'a>(
self: &mut &'a Self,
mut match_fn: impl FnMut(&'a Self, &T, Option<&T>) -> Match<M>,
) -> Result<M, Error<T::Span>> {
let mut result = None;
for i in (0..self.len()).rev() {
match match_fn(&self[i..], &self[i], (i > 0).then(|| &self[i - 1])) {
Match::Complete(m) => {
*self = &self[..i];
return Ok(m);
}
Match::Partial(m) => result = Some((m, &self[..i])),
Match::NeedMore => (),
Match::NoMatch => break,
}
}
result
.ok_or_else(|| self.error("no match"))
.map(|(result, rest)| {
*self = rest;
result
})
}
}
impl<T: TokenTree> Deref for TokenBuf<T> {
type Target = [T];
#[inline]
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl<T: TokenTree> DerefMut for TokenBuf<T> {
#[inline]
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.0
}
}
#[cfg(feature = "proc-macro")]
impl From<&TokenBuf<proc_macro::TokenTree>> for proc_macro::TokenStream {
#[inline]
fn from(value: &TokenBuf<proc_macro::TokenTree>) -> Self {
value.to_token_stream()
}
}
#[cfg(feature = "proc-macro")]
impl From<&mut TokenBuf<proc_macro::TokenTree>> for proc_macro::TokenStream {
#[inline]
fn from(value: &mut TokenBuf<proc_macro::TokenTree>) -> Self {
value.to_token_stream()
}
}
#[cfg(feature = "proc-macro2")]
impl From<&TokenBuf<proc_macro2::TokenTree>> for proc_macro2::TokenStream {
#[inline]
fn from(value: &TokenBuf<proc_macro2::TokenTree>) -> Self {
value.to_token_stream()
}
}
#[cfg(feature = "proc-macro2")]
impl From<&mut TokenBuf<proc_macro2::TokenTree>> for proc_macro2::TokenStream {
#[inline]
fn from(value: &mut TokenBuf<proc_macro2::TokenTree>) -> Self {
value.to_token_stream()
}
}
impl<'a, T: TokenTreeExt> From<&'a TokenBuffer<T>> for &'a TokenBuf<T> {
#[inline]
fn from(value: &'a TokenBuffer<T>) -> Self {
value.as_buf()
}
}
impl<'a, T: TokenTreeExt> From<&'a mut TokenBuffer<T>> for &'a mut TokenBuf<T> {
#[inline]
fn from(value: &'a mut TokenBuffer<T>) -> Self {
value.as_buf_mut()
}
}
impl<'a, T: TokenTreeExt> From<&'a [T]> for &'a TokenBuf<T> {
#[inline]
fn from(value: &'a [T]) -> Self {
TokenBuf::from_ref(value)
}
}
impl<'a, T: TokenTreeExt> From<&'a mut [T]> for &'a mut TokenBuf<T> {
#[inline]
fn from(value: &'a mut [T]) -> Self {
TokenBuf::from_mut(value)
}
}
impl<T: TokenTree, I: TokenBufferIndex<T>> Index<I> for TokenBuf<T> {
type Output = I::Output;
#[inline]
fn index(&self, index: I) -> &Self::Output {
index.index(&self.0)
}
}
impl<T: TokenTree, I: TokenBufferIndex<T>> IndexMut<I> for TokenBuf<T> {
#[inline]
fn index_mut(&mut self, index: I) -> &mut Self::Output {
index.index_mut(&mut self.0)
}
}
impl<'a, T: TokenTree> IntoIterator for &'a TokenBuf<T> {
type IntoIter = slice::Iter<'a, T>;
type Item = &'a T;
#[inline]
fn into_iter(self) -> Self::IntoIter {
self.0.iter()
}
}
impl<'a, T: TokenTree> IntoIterator for &'a mut TokenBuf<T> {
type IntoIter = slice::IterMut<'a, T>;
type Item = &'a mut T;
#[inline]
fn into_iter(self) -> Self::IntoIter {
self.0.iter_mut()
}
}
impl<T: TokenTreeExt> ToOwned for TokenBuf<T> {
type Owned = TokenBuffer<T>;
#[inline]
fn to_owned(&self) -> Self::Owned {
TokenBuffer(self.0.to_vec())
}
}
impl<T: TokenTree> ToTokens<T> for TokenBuf<T> {
#[inline]
fn to_tokens(&self) -> impl Iterator<Item = T> {
TokenBuffer::<T>(self.0.to_vec()).into_tokens()
}
}
impl<T: TokenStreamExt> ToTokenStream<T> for TokenBuf<T::TokenTree> {
#[inline]
fn extend_token_stream(&self, token_stream: &mut T) {
for i in self.0.iter() {
i.extend_token_stream(token_stream);
}
}
}
pub trait TokenBufferIndex<T: TokenTree> {
type Output: ?Sized;
fn index(self, slice: &[T]) -> &Self::Output;
fn index_mut(self, slice: &mut [T]) -> &mut Self::Output;
}
impl<T: TokenTree> TokenBufferIndex<T> for usize {
type Output = T;
#[inline]
fn index(self, slice: &[T]) -> &Self::Output {
&slice[self]
}
#[inline]
fn index_mut(self, slice: &mut [T]) -> &mut Self::Output {
&mut slice[self]
}
}
impl<T: TokenTreeExt> TokenBufferIndex<T> for Range<usize> {
type Output = TokenBuf<T>;
#[inline]
fn index(self, slice: &[T]) -> &Self::Output {
TokenBuf::from_ref(&slice[self.start..self.end])
}
#[inline]
fn index_mut(self, slice: &mut [T]) -> &mut Self::Output {
TokenBuf::from_mut(&mut slice[self.start..self.end])
}
}
impl<T: TokenTreeExt> TokenBufferIndex<T> for RangeFrom<usize> {
type Output = TokenBuf<T>;
#[inline]
fn index(self, slice: &[T]) -> &Self::Output {
TokenBuf::from_ref(&slice[self.start..])
}
#[inline]
fn index_mut(self, slice: &mut [T]) -> &mut Self::Output {
TokenBuf::from_mut(&mut slice[self.start..])
}
}
impl<T: TokenTreeExt> TokenBufferIndex<T> for RangeFull {
type Output = TokenBuf<T>;
#[inline]
fn index(self, slice: &[T]) -> &Self::Output {
TokenBuf::from_ref(slice)
}
#[inline]
fn index_mut(self, slice: &mut [T]) -> &mut Self::Output {
TokenBuf::from_mut(slice)
}
}
impl<T: TokenTreeExt> TokenBufferIndex<T> for RangeInclusive<usize> {
type Output = TokenBuf<T>;
#[inline]
fn index(self, slice: &[T]) -> &Self::Output {
TokenBuf::from_ref(&slice[*self.start()..=*self.end()])
}
#[inline]
fn index_mut(self, slice: &mut [T]) -> &mut Self::Output {
TokenBuf::from_mut(&mut slice[*self.start()..=*self.end()])
}
}
impl<T: TokenTreeExt> TokenBufferIndex<T> for RangeTo<usize> {
type Output = TokenBuf<T>;
#[inline]
fn index(self, slice: &[T]) -> &Self::Output {
TokenBuf::from_ref(&slice[..self.end])
}
#[inline]
fn index_mut(self, slice: &mut [T]) -> &mut Self::Output {
TokenBuf::from_mut(&mut slice[..self.end])
}
}
impl<T: TokenTreeExt> TokenBufferIndex<T> for RangeToInclusive<usize> {
type Output = TokenBuf<T>;
#[inline]
fn index(self, slice: &[T]) -> &Self::Output {
TokenBuf::from_ref(&slice[..=self.end])
}
#[inline]
fn index_mut(self, slice: &mut [T]) -> &mut Self::Output {
TokenBuf::from_mut(&mut slice[..=self.end])
}
}