use core::iter::FromIterator;
use core::convert::TryFrom;
use core::str::FromStr;
use core::hash::{Hash, Hasher};
use core::ops::{Deref, DerefMut, Index, IndexMut};
use core::fmt::{self, Debug, Display, Formatter};
use std::borrow::Cow;
use proc_macro2::{TokenStream, Span, Literal};
use ordered_float::NotNan;
use syn::spanned::Spanned;
use syn::ext::IdentExt;
use syn::parse::{Error, Result, Parse, ParseStream};
use syn::punctuated::{Pair, IntoIter, Iter, IterMut, IntoPairs, Pairs, PairsMut};
use quote::ToTokens;
pub use proc_macro2::Ident;
pub use syn::Token;
pub use syn::token;
pub fn ident(name: &str) -> Ident {
Ident::new(name, Span::call_site())
}
pub fn word(name: &str) -> Word {
Word::new(name, Span::call_site())
}
pub trait KeywordList {
const KEYWORDS: &'static [&'static str];
}
#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct CustomIdent<K> {
ident: Ident,
marker: K,
}
impl<K> CustomIdent<K> {
pub fn span(&self) -> Span {
self.ident.span()
}
pub fn set_span(&mut self, span: Span) {
self.ident.set_span(span);
}
}
impl<K, T> PartialEq<T> for CustomIdent<K>
where
T: AsRef<str>
{
fn eq(&self, other: &T) -> bool {
self.ident == other
}
}
impl<K> TryFrom<Ident> for CustomIdent<K>
where
K: Default + KeywordList
{
type Error = Error;
fn try_from(ident: Ident) -> Result<Self> {
if K::KEYWORDS.iter().any(|kw| ident == kw) {
Err(Error::new(ident.span(), "expected identifier, found keyword"))
} else {
Ok(CustomIdent {
ident,
marker: K::default(),
})
}
}
}
impl<K> From<CustomIdent<K>> for Ident {
fn from(ident: CustomIdent<K>) -> Self {
ident.ident
}
}
impl<K> Debug for CustomIdent<K> {
fn fmt(&self, formatter: &mut Formatter<'_>) -> fmt::Result {
Debug::fmt(&self.ident, formatter)
}
}
impl<K> Display for CustomIdent<K> {
fn fmt(&self, formatter: &mut Formatter<'_>) -> fmt::Result {
Display::fmt(&self.ident, formatter)
}
}
impl<K> FromStr for CustomIdent<K>
where
K: Default + KeywordList
{
type Err = Error;
fn from_str(string: &str) -> Result<Self> {
syn::parse_str(string)
}
}
impl<K> Parse for CustomIdent<K>
where
K: Default + KeywordList
{
fn parse(input: ParseStream<'_>) -> Result<Self> {
input.call(Ident::parse_any).and_then(CustomIdent::try_from)
}
}
impl<K> ToTokens for CustomIdent<K> {
fn to_tokens(&self, tokens: &mut TokenStream) {
self.ident.to_tokens(tokens);
}
}
#[derive(Clone, Copy, Default, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
pub struct AllowAll;
impl KeywordList for AllowAll {
const KEYWORDS: &'static [&'static str] = &[];
}
pub type Word = CustomIdent<AllowAll>;
impl Word {
pub fn new(string: &str, span: Span) -> Self {
Word {
ident: Ident::new(string, span),
marker: AllowAll,
}
}
}
#[macro_export]
macro_rules! define_keywords {
($vis:vis mod $modname:ident { $($kw:ident)* }) => {
$vis mod $modname {
$(::parsel::custom_keyword!($kw);)*
#[derive(Clone, Copy, Default, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
pub struct Keywords;
impl ::parsel::ast::KeywordList for Keywords {
const KEYWORDS: &'static [&'static str] = &[$(::core::stringify!($kw),)*];
}
}
}
}
#[derive(Clone, Copy, Default, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
pub struct Empty;
impl Empty {
pub const fn new() -> Self {
Empty
}
}
impl FromStr for Empty {
type Err = Error;
fn from_str(string: &str) -> Result<Self> {
syn::parse_str(string)
}
}
impl Display for Empty {
fn fmt(&self, _formatter: &mut Formatter<'_>) -> fmt::Result {
Ok(())
}
}
impl Parse for Empty {
fn parse(_input: ParseStream<'_>) -> Result<Self> {
Ok(Empty)
}
}
impl ToTokens for Empty {
fn to_tokens(&self, _tokens: &mut TokenStream) {}
}
#[derive(Clone, Copy, Default, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
pub struct Eof;
impl Eof {
pub const fn new() -> Self {
Eof
}
}
impl FromStr for Eof {
type Err = Error;
fn from_str(string: &str) -> Result<Self> {
syn::parse_str(string)
}
}
impl Display for Eof {
fn fmt(&self, _formatter: &mut Formatter<'_>) -> fmt::Result {
Ok(())
}
}
impl Parse for Eof {
fn parse(input: ParseStream<'_>) -> Result<Self> {
if input.is_empty() {
Ok(Eof)
} else {
Err(input.error("expected end of input or group, found garbage"))
}
}
}
impl ToTokens for Eof {
fn to_tokens(&self, _tokens: &mut TokenStream) {}
}
#[derive(Clone, Copy, Default, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
pub struct NotEof;
impl NotEof {
pub const fn new() -> Self {
NotEof
}
}
impl FromStr for NotEof {
type Err = Error;
fn from_str(string: &str) -> Result<Self> {
syn::parse_str(string)
}
}
impl Display for NotEof {
fn fmt(&self, _formatter: &mut Formatter<'_>) -> fmt::Result {
Ok(())
}
}
impl Parse for NotEof {
fn parse(input: ParseStream<'_>) -> Result<Self> {
if input.is_empty() {
Err(input.error("expected more input, found end of input"))
} else {
Ok(NotEof)
}
}
}
impl ToTokens for NotEof {
fn to_tokens(&self, _tokens: &mut TokenStream) {}
}
#[derive(Clone, Copy, PartialEq, Eq, Hash)]
pub struct Maybe<P, T> {
inner: Option<(P, T)>,
}
impl<P, T> Maybe<P, T> {
pub const fn new() -> Self {
Maybe { inner: None }
}
pub fn as_prefix(&self) -> Option<&P> {
self.inner.as_ref().map(|(prefix, _)| prefix)
}
pub fn as_prefix_mut(&mut self) -> Option<&mut P> {
self.inner.as_mut().map(|(prefix, _)| prefix)
}
pub fn into_prefix(self) -> Option<P> {
self.inner.map(|(prefix, _)| prefix)
}
pub fn as_ref(&self) -> Option<&T> {
self.inner.as_ref().map(|(_, inner)| inner)
}
pub fn as_mut(&mut self) -> Option<&mut T> {
self.inner.as_mut().map(|(_, inner)| inner)
}
pub fn into_inner(self) -> Option<T> {
self.inner.map(|(_, inner)| inner)
}
pub fn as_parts(&self) -> Option<&(P, T)> {
self.inner.as_ref()
}
pub fn as_parts_mut(&mut self) -> Option<&mut (P, T)> {
self.inner.as_mut()
}
pub fn into_parts(self) -> Option<(P, T)> {
self.inner
}
pub fn into_prefix_iter(self) -> core::option::IntoIter<P> {
self.into_prefix().into_iter()
}
pub fn prefix_iter(&self) -> core::option::IntoIter<&P> {
self.as_prefix().into_iter()
}
pub fn prefix_iter_mut(&mut self) -> core::option::IntoIter<&mut P> {
self.as_prefix_mut().into_iter()
}
pub fn iter(&self) -> core::option::IntoIter<&T> {
self.as_ref().into_iter()
}
pub fn iter_mut(&mut self) -> core::option::IntoIter<&mut T> {
self.as_mut().into_iter()
}
pub fn into_parts_iter(self) -> core::option::IntoIter<(P, T)> {
self.inner.into_iter()
}
pub fn parts_iter(&self) -> core::option::Iter<'_, (P, T)> {
self.inner.iter()
}
pub fn parts_iter_mut(&mut self) -> core::option::IterMut<'_, (P, T)> {
self.inner.iter_mut()
}
}
impl<P, T> Default for Maybe<P, T> {
fn default() -> Self {
Self::new()
}
}
impl<P, T> From<Option<(P, T)>> for Maybe<P, T> {
fn from(inner: Option<(P, T)>) -> Self {
Maybe { inner }
}
}
impl<P: Default, T> From<Option<T>> for Maybe<P, T> {
fn from(inner: Option<T>) -> Self {
Maybe {
inner: inner.map(|t| (P::default(), t))
}
}
}
impl<P, T> From<(P, T)> for Maybe<P, T> {
fn from(parts: (P, T)) -> Self {
Maybe { inner: parts.into() }
}
}
impl<P: Default, T> From<T> for Maybe<P, T> {
fn from(tail: T) -> Self {
let head = P::default();
let inner = (head, tail);
Maybe::from(inner)
}
}
impl<P, T> IntoIterator for Maybe<P, T> {
type Item = T;
type IntoIter = core::option::IntoIter<T>;
fn into_iter(self) -> Self::IntoIter {
self.into_inner().into_iter()
}
}
impl<'a, P, T> IntoIterator for &'a Maybe<P, T> {
type Item = &'a T;
type IntoIter = core::option::IntoIter<&'a T>;
fn into_iter(self) -> Self::IntoIter {
self.iter()
}
}
impl<'a, P, T> IntoIterator for &'a mut Maybe<P, T> {
type Item = &'a mut T;
type IntoIter = core::option::IntoIter<&'a mut T>;
fn into_iter(self) -> Self::IntoIter {
self.iter_mut()
}
}
impl<P, T> Deref for Maybe<P, T> {
type Target = Option<(P, T)>;
fn deref(&self) -> &Self::Target {
&self.inner
}
}
impl<P, T> DerefMut for Maybe<P, T> {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.inner
}
}
impl<P, T> Debug for Maybe<P, T>
where
P: Debug,
T: Debug,
{
fn fmt(&self, formatter: &mut Formatter<'_>) -> fmt::Result {
self.inner.fmt(formatter)
}
}
impl<P, T> Display for Maybe<P, T>
where
P: ToTokens,
T: ToTokens,
{
fn fmt(&self, formatter: &mut Formatter<'_>) -> fmt::Result {
Display::fmt(&self.to_token_stream(), formatter)
}
}
impl<P, T> FromStr for Maybe<P, T>
where
P: Parse,
T: Parse,
{
type Err = Error;
fn from_str(string: &str) -> Result<Self> {
syn::parse_str(string)
}
}
impl<P, T> Parse for Maybe<P, T>
where
P: Parse,
T: Parse,
{
fn parse(input: ParseStream<'_>) -> Result<Self> {
use syn::parse::discouraged::Speculative;
let fork = input.fork();
if let Ok(prefix) = fork.parse::<P>() {
input.advance_to(&fork);
let inner: T = input.parse()?;
Ok(Maybe {
inner: Some((prefix, inner)),
})
} else {
Ok(Self::default())
}
}
}
impl<P, T> ToTokens for Maybe<P, T>
where
P: ToTokens,
T: ToTokens,
{
fn to_tokens(&self, tokens: &mut TokenStream) {
if let Some((head, tail)) = &self.inner {
head.to_tokens(&mut *tokens);
tail.to_tokens(&mut *tokens);
}
}
}
#[derive(Clone, Copy, Default, PartialEq, Eq, Hash, Debug)]
pub struct Paren<T> {
parens: token::Paren,
inner: T,
}
impl<T> Paren<T> {
pub const fn new(inner: T, span: Span) -> Self {
let parens = token::Paren { span };
Paren { parens, inner }
}
pub fn into_inner(self) -> T {
self.inner
}
pub fn as_parens(&self) -> &token::Paren {
&self.parens
}
pub fn into_parens(self) -> token::Paren {
self.parens
}
pub fn as_parts(&self) -> (&token::Paren, &T) {
let Paren { parens, inner } = self;
(parens, inner)
}
pub fn into_parts(self) -> (token::Paren, T) {
let Paren { parens, inner } = self;
(parens, inner)
}
}
impl<T: Spanned> From<T> for Paren<T> {
fn from(inner: T) -> Self {
let parens = token::Paren(inner.span());
Paren { parens, inner }
}
}
impl<T> From<(token::Paren, T)> for Paren<T> {
fn from((parens, inner): (token::Paren, T)) -> Self {
Paren { parens, inner }
}
}
impl<T> Deref for Paren<T> {
type Target = T;
fn deref(&self) -> &Self::Target {
&self.inner
}
}
impl<T> AsRef<T> for Paren<T> {
fn as_ref(&self) -> &T {
&self.inner
}
}
impl<T: ToTokens> Display for Paren<T> {
fn fmt(&self, formatter: &mut Formatter<'_>) -> fmt::Result {
Display::fmt(&self.to_token_stream(), formatter)
}
}
impl<T: Parse> FromStr for Paren<T> {
type Err = Error;
fn from_str(string: &str) -> Result<Self> {
syn::parse_str(string)
}
}
impl<T: Parse> Parse for Paren<T> {
fn parse(input: ParseStream<'_>) -> Result<Self> {
let contents;
let parens = syn::parenthesized!(contents in input);
let inner = contents.parse()?;
Ok(Paren { parens, inner })
}
}
impl<T: ToTokens> ToTokens for Paren<T> {
fn to_tokens(&self, tokens: &mut TokenStream) {
self.parens.surround(tokens, |ts| self.inner.to_tokens(ts));
}
}
#[derive(Clone, Copy, Default, PartialEq, Eq, Hash, Debug)]
pub struct Bracket<T> {
brackets: token::Bracket,
inner: T,
}
impl<T> Bracket<T> {
pub const fn new(inner: T, span: Span) -> Self {
let brackets = token::Bracket { span };
Bracket { brackets, inner }
}
pub fn into_inner(self) -> T {
self.inner
}
pub fn as_brackets(&self) -> &token::Bracket {
&self.brackets
}
pub fn into_brackets(self) -> token::Bracket {
self.brackets
}
pub fn as_parts(&self) -> (&token::Bracket, &T) {
let Bracket { brackets, inner } = self;
(brackets, inner)
}
pub fn into_parts(self) -> (token::Bracket, T) {
let Bracket { brackets, inner } = self;
(brackets, inner)
}
}
impl<T: Spanned> From<T> for Bracket<T> {
fn from(inner: T) -> Self {
let brackets = token::Bracket(inner.span());
Bracket { brackets, inner }
}
}
impl<T> From<(token::Bracket, T)> for Bracket<T> {
fn from((brackets, inner): (token::Bracket, T)) -> Self {
Bracket { brackets, inner }
}
}
impl<T> Deref for Bracket<T> {
type Target = T;
fn deref(&self) -> &Self::Target {
&self.inner
}
}
impl<T> AsRef<T> for Bracket<T> {
fn as_ref(&self) -> &T {
&self.inner
}
}
impl<T: ToTokens> Display for Bracket<T> {
fn fmt(&self, formatter: &mut Formatter<'_>) -> fmt::Result {
Display::fmt(&self.to_token_stream(), formatter)
}
}
impl<T: Parse> FromStr for Bracket<T> {
type Err = Error;
fn from_str(string: &str) -> Result<Self> {
syn::parse_str(string)
}
}
impl<T: Parse> Parse for Bracket<T> {
fn parse(input: ParseStream<'_>) -> Result<Self> {
let contents;
let brackets = syn::bracketed!(contents in input);
let inner = contents.parse()?;
Ok(Bracket { brackets, inner })
}
}
impl<T: ToTokens> ToTokens for Bracket<T> {
fn to_tokens(&self, tokens: &mut TokenStream) {
self.brackets.surround(tokens, |ts| self.inner.to_tokens(ts));
}
}
#[derive(Clone, Copy, Default, PartialEq, Eq, Hash, Debug)]
pub struct Brace<T> {
braces: token::Brace,
inner: T,
}
impl<T> Brace<T> {
pub const fn new(inner: T, span: Span) -> Self {
let braces = token::Brace { span };
Brace { braces, inner }
}
pub fn into_inner(self) -> T {
self.inner
}
pub fn as_braces(&self) -> &token::Brace {
&self.braces
}
pub fn into_braces(self) -> token::Brace {
self.braces
}
pub fn as_parts(&self) -> (&token::Brace, &T) {
let Brace { braces, inner } = self;
(braces, inner)
}
pub fn into_parts(self) -> (token::Brace, T) {
let Brace { braces, inner } = self;
(braces, inner)
}
}
impl<T: Spanned> From<T> for Brace<T> {
fn from(inner: T) -> Self {
let braces = token::Brace(inner.span());
Brace { braces, inner }
}
}
impl<T> From<(token::Brace, T)> for Brace<T> {
fn from((braces, inner): (token::Brace, T)) -> Self {
Brace { braces, inner }
}
}
impl<T> Deref for Brace<T> {
type Target = T;
fn deref(&self) -> &Self::Target {
&self.inner
}
}
impl<T> AsRef<T> for Brace<T> {
fn as_ref(&self) -> &T {
&self.inner
}
}
impl<T: ToTokens> Display for Brace<T> {
fn fmt(&self, formatter: &mut Formatter<'_>) -> fmt::Result {
Display::fmt(&self.to_token_stream(), formatter)
}
}
impl<T: Parse> FromStr for Brace<T> {
type Err = Error;
fn from_str(string: &str) -> Result<Self> {
syn::parse_str(string)
}
}
impl<T: Parse> Parse for Brace<T> {
fn parse(input: ParseStream<'_>) -> Result<Self> {
let contents;
let braces = syn::braced!(contents in input);
let inner = contents.parse()?;
Ok(Brace { braces, inner })
}
}
impl<T: ToTokens> ToTokens for Brace<T> {
fn to_tokens(&self, tokens: &mut TokenStream) {
self.braces.surround(tokens, |ts| self.inner.to_tokens(ts));
}
}
#[derive(Clone, PartialEq, Eq, Hash)]
pub struct Punctuated<T, P> {
inner: syn::punctuated::Punctuated<T, P>,
}
impl<T, P> Punctuated<T, P> {
pub const fn new() -> Self {
Punctuated {
inner: syn::punctuated::Punctuated::new()
}
}
pub fn into_inner(self) -> syn::punctuated::Punctuated<T, P> {
self.inner
}
pub fn iter(&self) -> Iter<'_, T> {
self.inner.iter()
}
pub fn iter_mut(&mut self) -> IterMut<'_, T> {
self.inner.iter_mut()
}
pub fn into_pairs(self) -> IntoPairs<T, P> {
self.inner.into_pairs()
}
pub fn pairs(&self) -> Pairs<'_, T, P> {
self.inner.pairs()
}
pub fn pairs_mut(&mut self) -> PairsMut<'_, T, P> {
self.inner.pairs_mut()
}
}
impl<T, P> Default for Punctuated<T, P> {
fn default() -> Self {
Self::new()
}
}
impl<T, P> From<syn::punctuated::Punctuated<T, P>> for Punctuated<T, P> {
fn from(inner: syn::punctuated::Punctuated<T, P>) -> Self {
Punctuated { inner }
}
}
impl<T, P> From<Punctuated<T, P>> for syn::punctuated::Punctuated<T, P> {
fn from(punctuated: Punctuated<T, P>) -> Self {
punctuated.inner
}
}
impl<T, P> Deref for Punctuated<T, P> {
type Target = syn::punctuated::Punctuated<T, P>;
fn deref(&self) -> &Self::Target {
&self.inner
}
}
impl<T, P> DerefMut for Punctuated<T, P> {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.inner
}
}
impl<T, P> FromIterator<T> for Punctuated<T, P>
where
P: Default,
{
fn from_iter<I>(iter: I) -> Self
where
I: IntoIterator<Item = T>
{
Punctuated {
inner: iter.into_iter().collect()
}
}
}
impl<T, P> FromIterator<Pair<T, P>> for Punctuated<T, P> {
fn from_iter<I>(iter: I) -> Self
where
I: IntoIterator<Item = Pair<T, P>>
{
Punctuated {
inner: iter.into_iter().collect()
}
}
}
impl<T, P> Extend<T> for Punctuated<T, P>
where
P: Default,
{
fn extend<I>(&mut self, iter: I)
where
I: IntoIterator<Item = T>
{
self.inner.extend(iter);
}
}
impl<T, P> Extend<Pair<T, P>> for Punctuated<T, P> {
fn extend<I>(&mut self, iter: I)
where
I: IntoIterator<Item = Pair<T, P>>
{
self.inner.extend(iter);
}
}
impl<T, P> IntoIterator for Punctuated<T, P> {
type Item = T;
type IntoIter = IntoIter<T>;
fn into_iter(self) -> Self::IntoIter {
self.inner.into_iter()
}
}
impl<'a, T, P> IntoIterator for &'a Punctuated<T, P> {
type Item = &'a T;
type IntoIter = Iter<'a, T>;
fn into_iter(self) -> Self::IntoIter {
self.inner.iter()
}
}
impl<'a, T, P> IntoIterator for &'a mut Punctuated<T, P> {
type Item = &'a mut T;
type IntoIter = IterMut<'a, T>;
fn into_iter(self) -> Self::IntoIter {
self.inner.iter_mut()
}
}
impl<T, P> Index<usize> for Punctuated<T, P> {
type Output = T;
fn index(&self, index: usize) -> &Self::Output {
self.inner.index(index)
}
}
impl<T, P> IndexMut<usize> for Punctuated<T, P> {
fn index_mut(&mut self, index: usize) -> &mut Self::Output {
self.inner.index_mut(index)
}
}
impl<T, P> Debug for Punctuated<T, P>
where
T: Debug,
P: Debug,
{
fn fmt(&self, formatter: &mut Formatter<'_>) -> fmt::Result {
self.inner.fmt(formatter)
}
}
impl<T, P> Display for Punctuated<T, P>
where
T: ToTokens,
P: ToTokens,
{
fn fmt(&self, formatter: &mut Formatter<'_>) -> fmt::Result {
Display::fmt(&self.to_token_stream(), formatter)
}
}
impl<T, P> FromStr for Punctuated<T, P>
where
T: Parse,
P: Parse,
{
type Err = Error;
fn from_str(string: &str) -> Result<Self> {
syn::parse_str(string)
}
}
impl<T, P> Parse for Punctuated<T, P>
where
T: Parse,
P: Parse,
{
fn parse(input: ParseStream<'_>) -> Result<Self> {
let inner = syn::punctuated::Punctuated::parse_terminated(input)?;
Ok(Punctuated { inner })
}
}
impl<T, P> ToTokens for Punctuated<T, P>
where
T: ToTokens,
P: ToTokens,
{
fn to_tokens(&self, tokens: &mut TokenStream) {
let Punctuated { inner } = self;
inner.to_tokens(tokens);
}
}
pub type Many<T> = Punctuated<T, Empty>;
#[derive(Clone, PartialEq, Eq, Hash)]
pub struct Separated<T, P> {
inner: syn::punctuated::Punctuated<T, P>,
}
impl<T, P> Separated<T, P> {
pub fn into_inner(self) -> syn::punctuated::Punctuated<T, P> {
self.inner
}
pub fn first(&self) -> &T {
self.inner.first().expect("empty Separated")
}
pub fn first_mut(&mut self) -> &mut T {
self.inner.first_mut().expect("empty Separated")
}
pub fn last(&self) -> &T {
self.inner.last().expect("empty Separated")
}
pub fn last_mut(&mut self) -> &mut T {
self.inner.last_mut().expect("empty Separated")
}
pub fn insert(&mut self, index: usize, value: T)
where
P: Default
{
self.inner.insert(index, value);
}
pub fn push(&mut self, punct: P, value: T) {
self.inner.push_punct(punct);
self.inner.push_value(value);
}
pub fn push_value(&mut self, value: T)
where
P: Default,
{
self.push(P::default(), value);
}
pub fn iter(&self) -> Iter<'_, T> {
self.inner.iter()
}
pub fn iter_mut(&mut self) -> IterMut<'_, T> {
self.inner.iter_mut()
}
pub fn into_pairs(self) -> IntoPairs<T, P> {
self.inner.into_pairs()
}
pub fn pairs(&self) -> Pairs<'_, T, P> {
self.inner.pairs()
}
pub fn pairs_mut(&mut self) -> PairsMut<'_, T, P> {
self.inner.pairs_mut()
}
pub fn into_first_rest(self) -> (T, Vec<(P, T)>) {
let mut pairs = Vec::with_capacity(self.len() - 1);
let mut iter = self.into_pairs();
let pair = iter.next().expect("empty Separated");
let (first, mut punct) = match pair {
Pair::Punctuated(value, punct) => (value, punct),
Pair::End(value) => return (value, pairs),
};
for pair in iter {
match pair {
Pair::Punctuated(value, next) => {
pairs.push((punct, value));
punct = next;
}
Pair::End(value) => {
pairs.push((punct, value));
break;
}
}
}
(first, pairs)
}
pub fn into_last_rest(self) -> (T, Vec<(T, P)>) {
let mut pairs = Vec::with_capacity(self.len() - 1);
for pair in self.into_pairs() {
match pair {
Pair::Punctuated(value, punct) => {
pairs.push((value, punct));
}
Pair::End(value) => {
return (value, pairs);
}
}
}
unreachable!("empty Separated or trailing punctuation")
}
}
impl<T, P> TryFrom<syn::punctuated::Punctuated<T, P>> for Separated<T, P>
where
T: ToTokens,
P: ToTokens,
{
type Error = Error;
fn try_from(inner: syn::punctuated::Punctuated<T, P>) -> Result<Self> {
if inner.empty_or_trailing() {
Err(Error::new(inner.span(), "empty sequence or trailing punctuation"))
} else {
Ok(Separated { inner })
}
}
}
impl<T, P> From<Separated<T, P>> for syn::punctuated::Punctuated<T, P> {
fn from(separated: Separated<T, P>) -> Self {
separated.inner
}
}
impl<T, P> Deref for Separated<T, P> {
type Target = syn::punctuated::Punctuated<T, P>;
fn deref(&self) -> &Self::Target {
&self.inner
}
}
impl<T, P> Extend<T> for Separated<T, P>
where
P: Default,
{
fn extend<I>(&mut self, iter: I)
where
I: IntoIterator<Item = T>
{
self.inner.extend(iter);
}
}
impl<T, P> Extend<(P, T)> for Separated<T, P> {
fn extend<I>(&mut self, iter: I)
where
I: IntoIterator<Item = (P, T)>
{
for (punct, value) in iter {
self.push(punct, value);
}
}
}
impl<T, P> IntoIterator for Separated<T, P> {
type Item = T;
type IntoIter = IntoIter<T>;
fn into_iter(self) -> Self::IntoIter {
self.inner.into_iter()
}
}
impl<'a, T, P> IntoIterator for &'a Separated<T, P> {
type Item = &'a T;
type IntoIter = Iter<'a, T>;
fn into_iter(self) -> Self::IntoIter {
self.inner.iter()
}
}
impl<'a, T, P> IntoIterator for &'a mut Separated<T, P> {
type Item = &'a mut T;
type IntoIter = IterMut<'a, T>;
fn into_iter(self) -> Self::IntoIter {
self.inner.iter_mut()
}
}
impl<T, P> Index<usize> for Separated<T, P> {
type Output = T;
fn index(&self, index: usize) -> &Self::Output {
self.inner.index(index)
}
}
impl<T, P> IndexMut<usize> for Separated<T, P> {
fn index_mut(&mut self, index: usize) -> &mut Self::Output {
self.inner.index_mut(index)
}
}
impl<T, P> Debug for Separated<T, P>
where
T: Debug,
P: Debug,
{
fn fmt(&self, formatter: &mut Formatter<'_>) -> fmt::Result {
self.inner.fmt(formatter)
}
}
impl<T, P> Display for Separated<T, P>
where
T: ToTokens,
P: ToTokens,
{
fn fmt(&self, formatter: &mut Formatter<'_>) -> fmt::Result {
Display::fmt(&self.to_token_stream(), formatter)
}
}
impl<T, P> FromStr for Separated<T, P>
where
T: Parse,
P: Parse,
{
type Err = Error;
fn from_str(string: &str) -> Result<Self> {
syn::parse_str(string)
}
}
impl<T, P> Parse for Separated<T, P>
where
T: Parse,
P: Parse,
{
fn parse(input: ParseStream<'_>) -> Result<Self> {
use crate::syn::parse::discouraged::Speculative;
let head: T = input.parse()?;
let mut inner = syn::punctuated::Punctuated::new();
inner.push_value(head);
loop {
let fork = input.fork();
if let Ok(punct) = fork.parse::<P>() {
input.advance_to(&fork);
let value: T = input.parse()?;
inner.push_punct(punct);
inner.push_value(value);
} else {
break;
}
}
Ok(Separated { inner })
}
}
impl<T, P> ToTokens for Separated<T, P>
where
T: ToTokens,
P: ToTokens,
{
fn to_tokens(&self, tokens: &mut TokenStream) {
let Separated { inner } = self;
inner.to_tokens(tokens);
}
}
macro_rules! impl_literal {
($($raw:ty => $name:ident;)*) => {$(
#[derive(Clone, Debug)]
pub struct $name {
value: $raw,
span: Span,
}
impl $name {
pub fn new(value: $raw, span: Span) -> Self {
$name { value, span }
}
pub fn value(&self) -> $raw {
self.value.clone()
}
pub fn into_inner(self) -> $raw {
self.value
}
pub fn span(&self) -> Span {
self.span
}
pub fn set_span(&mut self, span: Span) {
self.span = span;
}
}
impl Default for $name {
fn default() -> Self {
$name {
value: <$raw>::default(),
span: Span::call_site(),
}
}
}
impl From<$raw> for $name {
fn from(value: $raw) -> Self {
let span = Span::call_site();
$name { value, span }
}
}
impl From<$name> for $raw {
fn from(lit: $name) -> $raw {
lit.value
}
}
impl PartialEq<Self> for $name {
fn eq(&self, other: &Self) -> bool {
self.value == other.value
}
}
impl PartialEq<$raw> for $name {
fn eq(&self, value: &$raw) -> bool {
self.value == *value
}
}
impl Eq for $name {}
impl Hash for $name {
fn hash<H: Hasher>(&self, state: &mut H) {
self.value.hash(state);
}
}
impl Display for $name {
fn fmt(&self, formatter: &mut Formatter<'_>) -> fmt::Result {
Display::fmt(&self.token(), formatter)
}
}
impl FromStr for $name {
type Err = Error;
fn from_str(string: &str) -> Result<Self> {
syn::parse_str(string)
}
}
impl ToTokens for $name {
fn to_tokens(&self, tokens: &mut TokenStream) {
self.token().to_tokens(tokens);
}
}
)*}
}
impl_literal!{
bool => LitBool;
u8 => LitByte;
i128 => LitInt;
u128 => LitUint;
NotNan<f64> => LitFloat;
char => LitChar;
String => LitStr;
Vec<u8> => LitByteStr;
}
impl LitBool {
pub fn token(&self) -> Ident {
let repr = if self.value { "true" } else { "false" };
Ident::new(repr, self.span)
}
}
impl LitByte {
pub fn token(&self) -> Literal {
use std::{str, ascii};
use std::io::{Write, Cursor};
let mut buf: [u8; 8] = Default::default();
let mut cursor = Cursor::new(buf.as_mut());
let escape = ascii::escape_default(self.value);
write!(cursor, r"b'{}'", escape).expect("cannot escape byte literal");
#[allow(clippy::cast_possible_truncation)]
let len = cursor.position() as usize;
let bytes = &buf[..len];
let repr = str::from_utf8(bytes).expect("invalid UTF-8 in byte literal");
let mut lit = Literal::from_str(repr).expect("unparseable byte literal");
lit.set_span(self.span);
lit
}
}
impl LitInt {
pub fn token(&self) -> Literal {
let mut lit = Literal::i128_unsuffixed(self.value);
lit.set_span(self.span);
lit
}
}
impl LitUint {
pub fn token(&self) -> Literal {
let mut lit = Literal::u128_unsuffixed(self.value);
lit.set_span(self.span);
lit
}
}
impl LitFloat {
pub fn token(&self) -> Literal {
let mut lit = Literal::f64_unsuffixed(self.value.into_inner());
lit.set_span(self.span);
lit
}
}
impl LitChar {
pub fn token(&self) -> Literal {
let mut lit = Literal::character(self.value);
lit.set_span(self.span);
lit
}
}
impl LitStr {
pub fn token(&self) -> Literal {
let mut lit = Literal::string(&self.value);
lit.set_span(self.span);
lit
}
}
impl LitByteStr {
pub fn token(&self) -> Literal {
let mut lit = Literal::byte_string(&self.value);
lit.set_span(self.span);
lit
}
}
impl Copy for LitBool {}
impl Copy for LitByte {}
impl Copy for LitInt {}
impl Copy for LitUint {}
impl Copy for LitFloat {}
impl Copy for LitChar {}
impl From<syn::LitBool> for LitBool {
fn from(lit: syn::LitBool) -> Self {
LitBool::new(lit.value, lit.span)
}
}
impl From<LitBool> for syn::LitBool {
fn from(lit: LitBool) -> Self {
syn::LitBool::new(lit.value, lit.span)
}
}
impl From<syn::LitByte> for LitByte {
fn from(lit: syn::LitByte) -> Self {
LitByte::new(lit.value(), lit.span())
}
}
impl From<LitByte> for syn::LitByte {
fn from(lit: LitByte) -> Self {
syn::LitByte::new(lit.value, lit.span)
}
}
impl TryFrom<syn::LitInt> for LitInt {
type Error = Error;
fn try_from(lit: syn::LitInt) -> Result<Self> {
let value: i128 = lit.base10_parse()?;
let span = lit.span();
Ok(LitInt::new(value, span))
}
}
impl From<LitInt> for syn::LitInt {
fn from(lit: LitInt) -> Self {
lit.token().into()
}
}
impl TryFrom<syn::LitInt> for LitUint {
type Error = Error;
fn try_from(lit: syn::LitInt) -> Result<Self> {
let value: u128 = lit.base10_parse()?;
let span = lit.span();
Ok(LitUint::new(value, span))
}
}
impl From<LitUint> for syn::LitInt {
fn from(lit: LitUint) -> Self {
lit.token().into()
}
}
impl TryFrom<syn::LitFloat> for LitFloat {
type Error = Error;
fn try_from(lit: syn::LitFloat) -> Result<Self> {
let value: NotNan<f64> = lit.base10_parse()?;
let span = lit.span();
Ok(LitFloat::new(value, span))
}
}
impl From<LitFloat> for syn::LitFloat {
fn from(lit: LitFloat) -> Self {
lit.token().into()
}
}
impl TryFrom<f64> for LitFloat {
type Error = ordered_float::FloatIsNan;
fn try_from(x: f64) -> core::result::Result<Self, Self::Error> {
let value = NotNan::try_from(x)?;
let span = Span::call_site();
Ok(LitFloat { value, span })
}
}
impl From<LitFloat> for f64 {
fn from(lit: LitFloat) -> f64 {
lit.value.into_inner()
}
}
impl From<syn::LitChar> for LitChar {
fn from(lit: syn::LitChar) -> Self {
LitChar::new(lit.value(), lit.span())
}
}
impl From<LitChar> for syn::LitChar {
fn from(lit: LitChar) -> Self {
syn::LitChar::new(lit.value, lit.span)
}
}
impl From<syn::LitStr> for LitStr {
fn from(lit: syn::LitStr) -> Self {
LitStr::new(lit.value(), lit.span())
}
}
impl From<LitStr> for syn::LitStr {
fn from(lit: LitStr) -> Self {
syn::LitStr::new(&lit.value, lit.span)
}
}
impl From<&str> for LitStr {
fn from(value: &str) -> LitStr {
LitStr::new(value.to_owned(), Span::call_site())
}
}
impl From<Box<str>> for LitStr {
fn from(value: Box<str>) -> LitStr {
LitStr::new(value.into(), Span::call_site())
}
}
impl From<Cow<'_, str>> for LitStr {
fn from(value: Cow<'_, str>) -> LitStr {
LitStr::new(value.into_owned(), Span::call_site())
}
}
impl From<LitStr> for Box<str> {
fn from(lit: LitStr) -> Self {
lit.value.into_boxed_str()
}
}
impl From<LitStr> for Cow<'_, str> {
fn from(lit: LitStr) -> Self {
lit.value.into()
}
}
impl AsRef<str> for LitStr {
fn as_ref(&self) -> &str {
&self.value
}
}
impl Deref for LitStr {
type Target = str;
fn deref(&self) -> &Self::Target {
&self.value
}
}
impl From<syn::LitByteStr> for LitByteStr {
fn from(lit: syn::LitByteStr) -> Self {
LitByteStr::new(lit.value(), lit.span())
}
}
impl From<LitByteStr> for syn::LitByteStr {
fn from(lit: LitByteStr) -> Self {
syn::LitByteStr::new(&lit.value, lit.span())
}
}
impl From<&[u8]> for LitByteStr {
fn from(value: &[u8]) -> Self {
LitByteStr::new(value.to_vec(), Span::call_site())
}
}
impl From<Box<[u8]>> for LitByteStr {
fn from(value: Box<[u8]>) -> Self {
LitByteStr::new(value.into(), Span::call_site())
}
}
impl From<Cow<'_, [u8]>> for LitByteStr {
fn from(value: Cow<'_, [u8]>) -> Self {
LitByteStr::new(value.into_owned(), Span::call_site())
}
}
impl From<LitByteStr> for Box<[u8]> {
fn from(lit: LitByteStr) -> Self {
lit.value.into_boxed_slice()
}
}
impl From<LitByteStr> for Cow<'_, [u8]> {
fn from(lit: LitByteStr) -> Self {
lit.value.into()
}
}
impl AsRef<[u8]> for LitByteStr {
fn as_ref(&self) -> &[u8] {
&self.value
}
}
impl AsMut<[u8]> for LitByteStr {
fn as_mut(&mut self) -> &mut [u8] {
&mut self.value
}
}
impl Deref for LitByteStr {
type Target = [u8];
fn deref(&self) -> &Self::Target {
&self.value
}
}
impl DerefMut for LitByteStr {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.value
}
}
impl Parse for LitBool {
fn parse(input: ParseStream<'_>) -> Result<Self> {
input.parse::<syn::LitBool>().map(LitBool::from)
}
}
impl Parse for LitByte {
fn parse(input: ParseStream<'_>) -> Result<Self> {
input.parse::<syn::LitByte>().map(LitByte::from)
}
}
impl Parse for LitInt {
fn parse(input: ParseStream<'_>) -> Result<Self> {
input.parse::<syn::LitInt>().and_then(LitInt::try_from)
}
}
impl Parse for LitUint {
fn parse(input: ParseStream<'_>) -> Result<Self> {
input.parse::<syn::LitInt>().and_then(LitUint::try_from)
}
}
impl Parse for LitFloat {
fn parse(input: ParseStream<'_>) -> Result<Self> {
input.parse::<syn::LitFloat>().and_then(LitFloat::try_from)
}
}
impl Parse for LitChar {
fn parse(input: ParseStream<'_>) -> Result<Self> {
input.parse::<syn::LitChar>().map(LitChar::from)
}
}
impl Parse for LitStr {
fn parse(input: ParseStream<'_>) -> Result<Self> {
input.parse::<syn::LitStr>().map(LitStr::from)
}
}
impl Parse for LitByteStr {
fn parse(input: ParseStream<'_>) -> Result<Self> {
input.parse::<syn::LitByteStr>().map(LitByteStr::from)
}
}
#[derive(Clone, PartialEq, Eq, Hash)]
pub enum Lit {
Bool(LitBool),
Byte(LitByte),
Int(LitInt),
Uint(LitUint),
Float(LitFloat),
Char(LitChar),
Str(LitStr),
ByteStr(LitByteStr),
}
impl Lit {
pub fn span(&self) -> Span {
match self {
Lit::Bool(lit) => lit.span(),
Lit::Byte(lit) => lit.span(),
Lit::Int(lit) => lit.span(),
Lit::Uint(lit) => lit.span(),
Lit::Float(lit) => lit.span(),
Lit::Char(lit) => lit.span(),
Lit::Str(lit) => lit.span(),
Lit::ByteStr(lit) => lit.span(),
}
}
pub fn set_span(&mut self, new_span: Span) {
match self {
Lit::Bool(lit) => lit.set_span(new_span),
Lit::Byte(lit) => lit.set_span(new_span),
Lit::Int(lit) => lit.set_span(new_span),
Lit::Uint(lit) => lit.set_span(new_span),
Lit::Float(lit) => lit.set_span(new_span),
Lit::Char(lit) => lit.set_span(new_span),
Lit::Str(lit) => lit.set_span(new_span),
Lit::ByteStr(lit) => lit.set_span(new_span),
}
}
}
impl From<LitBool> for Lit {
fn from(lit: LitBool) -> Self {
Lit::Bool(lit)
}
}
impl From<bool> for Lit {
fn from(value: bool) -> Self {
Lit::Bool(value.into())
}
}
impl From<LitByte> for Lit {
fn from(lit: LitByte) -> Self {
Lit::Byte(lit)
}
}
impl From<u8> for Lit {
fn from(value: u8) -> Self {
Lit::Byte(value.into())
}
}
impl From<LitInt> for Lit {
fn from(lit: LitInt) -> Self {
Lit::Int(lit)
}
}
impl From<i128> for Lit {
fn from(value: i128) -> Self {
Lit::Int(value.into())
}
}
impl From<LitUint> for Lit {
fn from(lit: LitUint) -> Self {
Lit::Uint(lit)
}
}
impl From<u128> for Lit {
fn from(value: u128) -> Self {
Lit::Uint(value.into())
}
}
impl From<LitFloat> for Lit {
fn from(lit: LitFloat) -> Self {
Lit::Float(lit)
}
}
impl From<NotNan<f64>> for Lit {
fn from(value: NotNan<f64>) -> Self {
Lit::Float(value.into())
}
}
impl TryFrom<f64> for Lit {
type Error = ordered_float::FloatIsNan;
fn try_from(value: f64) -> core::result::Result<Self, Self::Error> {
LitFloat::try_from(value).map(Lit::Float)
}
}
impl From<LitChar> for Lit {
fn from(lit: LitChar) -> Self {
Lit::Char(lit)
}
}
impl From<char> for Lit {
fn from(value: char) -> Self {
Lit::Char(value.into())
}
}
impl From<LitStr> for Lit {
fn from(lit: LitStr) -> Self {
Lit::Str(lit)
}
}
impl From<String> for Lit {
fn from(value: String) -> Self {
Lit::Str(value.into())
}
}
impl From<&str> for Lit {
fn from(value: &str) -> Self {
Lit::Str(value.into())
}
}
impl From<Box<str>> for Lit {
fn from(value: Box<str>) -> Self {
Lit::Str(value.into())
}
}
impl From<Cow<'_, str>> for Lit {
fn from(value: Cow<'_, str>) -> Self {
Lit::Str(value.into())
}
}
impl From<LitByteStr> for Lit {
fn from(lit: LitByteStr) -> Self {
Lit::ByteStr(lit)
}
}
impl From<Vec<u8>> for Lit {
fn from(value: Vec<u8>) -> Self {
Lit::ByteStr(value.into())
}
}
impl From<&[u8]> for Lit {
fn from(value: &[u8]) -> Self {
Lit::ByteStr(value.into())
}
}
impl From<Box<[u8]>> for Lit {
fn from(value: Box<[u8]>) -> Self {
Lit::ByteStr(value.into())
}
}
impl From<Cow<'_, [u8]>> for Lit {
fn from(value: Cow<'_, [u8]>) -> Self {
Lit::ByteStr(value.into())
}
}
impl From<Lit> for syn::Lit {
fn from(lit: Lit) -> Self {
match lit {
Lit::Bool(lit) => syn::Lit::Bool(lit.into()),
Lit::Byte(lit) => syn::Lit::Byte(lit.into()),
Lit::Int(lit) => syn::Lit::Int(lit.into()),
Lit::Uint(lit) => syn::Lit::Int(lit.into()),
Lit::Float(lit) => syn::Lit::Float(lit.into()),
Lit::Char(lit) => syn::Lit::Char(lit.into()),
Lit::Str(lit) => syn::Lit::Str(lit.into()),
Lit::ByteStr(lit) => syn::Lit::ByteStr(lit.into()),
}
}
}
impl TryFrom<syn::Lit> for Lit {
type Error = Error;
fn try_from(lit: syn::Lit) -> Result<Self> {
match lit {
syn::Lit::Bool(lit) => Ok(Lit::Bool(lit.into())),
syn::Lit::Byte(lit) => Ok(Lit::Byte(lit.into())),
syn::Lit::Int(lit) => {
if lit.base10_digits().trim().starts_with('-') {
LitInt::try_from(lit).map(Lit::Int)
} else {
LitUint::try_from(lit).map(Lit::Uint)
}
}
syn::Lit::Float(lit) => LitFloat::try_from(lit).map(Lit::Float),
syn::Lit::Char(lit) => Ok(Lit::Char(lit.into())),
syn::Lit::Str(lit) => Ok(Lit::Str(lit.into())),
syn::Lit::ByteStr(lit) => Ok(Lit::ByteStr(lit.into())),
syn::Lit::Verbatim(lit) => {
Err(Error::new(lit.span(), format!("unparseable literal `{:?}`", lit)))
}
}
}
}
impl Debug for Lit {
fn fmt(&self, formatter: &mut Formatter<'_>) -> fmt::Result {
match self {
Lit::Bool(lit) => Debug::fmt(lit, formatter),
Lit::Byte(lit) => Debug::fmt(lit, formatter),
Lit::Int(lit) => Debug::fmt(lit, formatter),
Lit::Uint(lit) => Debug::fmt(lit, formatter),
Lit::Float(lit) => Debug::fmt(lit, formatter),
Lit::Char(lit) => Debug::fmt(lit, formatter),
Lit::Str(lit) => Debug::fmt(lit, formatter),
Lit::ByteStr(lit) => Debug::fmt(lit, formatter),
}
}
}
impl Display for Lit {
fn fmt(&self, formatter: &mut Formatter<'_>) -> fmt::Result {
match self {
Lit::Bool(lit) => Display::fmt(lit, formatter),
Lit::Byte(lit) => Display::fmt(lit, formatter),
Lit::Int(lit) => Display::fmt(lit, formatter),
Lit::Uint(lit) => Display::fmt(lit, formatter),
Lit::Float(lit) => Display::fmt(lit, formatter),
Lit::Char(lit) => Display::fmt(lit, formatter),
Lit::Str(lit) => Display::fmt(lit, formatter),
Lit::ByteStr(lit) => Display::fmt(lit, formatter),
}
}
}
impl FromStr for Lit {
type Err = Error;
fn from_str(string: &str) -> Result<Self> {
syn::parse_str(string)
}
}
impl Parse for Lit {
fn parse(input: ParseStream<'_>) -> Result<Self> {
syn::Lit::parse(input).and_then(Lit::try_from)
}
}
impl ToTokens for Lit {
fn to_tokens(&self, tokens: &mut TokenStream) {
match self {
Lit::Bool(lit) => lit.to_tokens(tokens),
Lit::Byte(lit) => lit.to_tokens(tokens),
Lit::Int(lit) => lit.to_tokens(tokens),
Lit::Uint(lit) => lit.to_tokens(tokens),
Lit::Float(lit) => lit.to_tokens(tokens),
Lit::Char(lit) => lit.to_tokens(tokens),
Lit::Str(lit) => lit.to_tokens(tokens),
Lit::ByteStr(lit) => lit.to_tokens(tokens),
}
}
}
#[derive(Clone, PartialEq, Eq, Hash)]
pub enum LeftAssoc<O, R> {
Binary {
lhs: Box<Self>,
op: O,
rhs: R,
},
Rhs(R),
}
impl<O, R> From<R> for LeftAssoc<O, R> {
fn from(rhs: R) -> Self {
LeftAssoc::Rhs(rhs)
}
}
impl<O, R> Debug for LeftAssoc<O, R>
where
O: Debug,
R: Debug,
{
fn fmt(&self, formatter: &mut Formatter<'_>) -> fmt::Result {
match self {
LeftAssoc::Binary { lhs, op, rhs } => {
let name = format!("Binary<{:?}>", op);
formatter.debug_struct(&name)
.field("lhs", lhs)
.field("rhs", rhs)
.finish()
}
LeftAssoc::Rhs(rhs) => Debug::fmt(rhs, formatter)
}
}
}
impl<O, R> Display for LeftAssoc<O, R>
where
O: ToTokens,
R: ToTokens,
{
fn fmt(&self, formatter: &mut Formatter<'_>) -> fmt::Result {
Display::fmt(&self.to_token_stream(), formatter)
}
}
impl<O, R> FromStr for LeftAssoc<O, R>
where
O: Parse,
R: Parse,
{
type Err = Error;
fn from_str(string: &str) -> Result<Self> {
syn::parse_str(string)
}
}
impl<O, R> Parse for LeftAssoc<O, R>
where
O: Parse,
R: Parse,
{
fn parse(input: ParseStream<'_>) -> Result<Self> {
let seq: Separated<R, O> = input.parse()?;
let (first, rest) = seq.into_first_rest();
let mut expr = LeftAssoc::Rhs(first);
for (op, rhs) in rest {
expr = LeftAssoc::Binary {
lhs: Box::new(expr),
op,
rhs,
};
}
Ok(expr)
}
}
impl<O, R> ToTokens for LeftAssoc<O, R>
where
O: ToTokens,
R: ToTokens,
{
fn to_tokens(&self, tokens: &mut TokenStream) {
match self {
LeftAssoc::Binary { lhs, op, rhs } => {
lhs.to_tokens(&mut *tokens);
op.to_tokens(&mut *tokens);
rhs.to_tokens(&mut *tokens);
}
LeftAssoc::Rhs(rhs) => {
rhs.to_tokens(tokens);
}
}
}
}
#[derive(Clone, PartialEq, Eq, Hash)]
pub enum RightAssoc<O, L> {
Binary {
lhs: L,
op: O,
rhs: Box<Self>,
},
Lhs(L),
}
impl<O, L> From<L> for RightAssoc<O, L> {
fn from(lhs: L) -> Self {
RightAssoc::Lhs(lhs)
}
}
impl<O, L> Debug for RightAssoc<O, L>
where
O: Debug,
L: Debug,
{
fn fmt(&self, formatter: &mut Formatter<'_>) -> fmt::Result {
match self {
RightAssoc::Binary { lhs, op, rhs } => {
let name = format!("Binary<{:?}>", op);
formatter.debug_struct(&name)
.field("lhs", lhs)
.field("rhs", rhs)
.finish()
}
RightAssoc::Lhs(lhs) => Debug::fmt(lhs, formatter)
}
}
}
impl<O, L> Display for RightAssoc<O, L>
where
O: ToTokens,
L: ToTokens,
{
fn fmt(&self, formatter: &mut Formatter<'_>) -> fmt::Result {
Display::fmt(&self.to_token_stream(), formatter)
}
}
impl<O, L> FromStr for RightAssoc<O, L>
where
O: Parse,
L: Parse,
{
type Err = Error;
fn from_str(string: &str) -> Result<Self> {
syn::parse_str(string)
}
}
impl<O, L> Parse for RightAssoc<O, L>
where
O: Parse,
L: Parse,
{
fn parse(input: ParseStream<'_>) -> Result<Self> {
let seq: Separated<L, O> = input.parse()?;
let (last, rest) = seq.into_last_rest();
let mut expr = RightAssoc::Lhs(last);
for (lhs, op) in rest.into_iter().rev() {
expr = RightAssoc::Binary {
lhs,
op,
rhs: Box::new(expr),
};
}
Ok(expr)
}
}
impl<O, L> ToTokens for RightAssoc<O, L>
where
O: ToTokens,
L: ToTokens,
{
fn to_tokens(&self, tokens: &mut TokenStream) {
match self {
RightAssoc::Binary { lhs, op, rhs } => {
lhs.to_tokens(&mut *tokens);
op.to_tokens(&mut *tokens);
rhs.to_tokens(&mut *tokens);
}
RightAssoc::Lhs(lhs) => {
lhs.to_tokens(tokens);
}
}
}
}