#[cfg(doc)]
use proc_macro2::{Span, TokenTree};
#[cfg(doc)]
use crate::{IntoTokens, grammar, quote_into_mixed_site, raw_quote_into_mixed_site};
#[macro_export]
macro_rules! grammar {
{
$(#[$($attr:tt)*])*
$vis:vis enum $name:ident$(: $(
$(doc $(@ $doc:tt)?)?
$(PeekFrom $(@ $PeekFrom:tt)?)?
$(PopFrom $(@ $PopFrom:tt)?)?
$(IntoTokens $(@ $IntoTokens:tt)?)?
),*)? {$(
$(#[$($variant_attr:tt)*])*
$variant:ident($($type:ty),*$(,)?)
),*$(,)?} else $error:expr;
$($tt:tt)*
} => {
#[cfg_attr(any($($($(all(), $(@ $doc)?)?)?)*), doc = $crate::grammar!(@enum_doc [$([$($type,)*])*]))]
$(#[$($attr)*])*
$vis enum $name {$(
$(#[$($variant_attr)*])*
$variant($($type),*),
)*}
#[cfg(any($($($(all(), $(@ $PeekFrom)?)?)?)*))]
impl $crate::PeekFrom for $name {
fn peek_from(input: &$crate::Input) -> $crate::__::bool {
false
$(|| $crate::grammar!(@peek_first $name input $($type,)*))*
}
}
#[cfg(any($($($(all(), $(@ $PopFrom)?)?)?)*))]
impl $crate::PopFrom for $name {
fn pop_from(input: &mut $crate::Input, errors: &mut $crate::Errors) -> $crate::__::Result<Self, ()> {
$crate::__::Result::Ok($(if let Some(values) = ($(<$type as $crate::PopFrom>::peek_pop_from(input, errors)?),*) {
Self::$variant(values)
} else)* {
return $crate::__::Result::Err(errors.push($crate::Error::new(
$crate::ErrorPriority::GRAMMAR,
$error,
[input.front_span()],
)));
})
}
}
#[cfg(any($($($(all(), $(@ $IntoTokens)?)?)?)*))]
impl $crate::IntoTokens for $name {
fn into_tokens(self, root: &$crate::__::TokenStream, tokens: &mut impl $crate::__::Extend<$crate::__::TokenTree>) {
match self {
$(Self::$variant(value) => $crate::IntoTokens::into_tokens(value, root, tokens),)*
}
}
}
$crate::grammar!($($tt)*);
};
{
$(#[$($attr:tt)*])*
$vis:vis struct $name:ident$(: $(
$(PeekFrom $(@ $PeekFrom:tt)?)?
$(PopFrom $(@ $PopFrom:tt)?)?
$(IntoTokens $(@ $IntoTokens:tt)?)?
),*)? {$(
$(#[$($field_attr:tt)*])*
$field_vis:vis $field:ident: $type:ty
),*$(,)?}
$($tt:tt)*
} => {
$(#[$($attr)*])*
$vis struct $name {$(
$(#[$($field_attr)*])*
$field_vis $field: $type,
)*}
#[cfg(any($($($(all(), $(@ $PeekFrom)?)?)?)*))]
impl $crate::PeekFrom for $name {
fn peek_from(input: &$crate::Input) -> $crate::__::bool {
$crate::grammar!(@peek_first $name input $($type,)*)
}
}
#[cfg(any($($($(all(), $(@ $PopFrom)?)?)?)*))]
impl $crate::PopFrom for $name {
fn pop_from(input: &mut $crate::Input, errors: &mut $crate::Errors) -> $crate::__::Result<Self, ()> {
$crate::__::Result::Ok(Self {
$($field: <$type as $crate::PopFrom>::pop_from(input, errors)?,)*
})
}
}
#[cfg(any($($($(all(), $(@ $IntoTokens)?)?)?)*))]
impl $crate::IntoTokens for $name {
fn into_tokens(self, root: &$crate::__::TokenStream, tokens: &mut impl $crate::__::Extend<$crate::__::TokenTree>) {
let Self {
$($field,)*
} = self;
$($crate::IntoTokens::into_tokens($field, root, tokens);)*
}
}
$crate::grammar!($($tt)*);
};
{
$(#[$($attr:tt)*])*
$vis:vis struct $name:ident$(: $(
$(PeekFrom $(@ $PeekFrom:tt)?)?
$(PopFrom $(@ $PopFrom:tt)?)?
),*)? ($(
$(#[$($field_attr:tt)*])*
$field_vis:vis $type:ty
),*$(,)?);
$($tt:tt)*
} => {
$(#[$($attr)*])*
$vis struct $name ($(
$(#[$($field_attr)*])*
$field_vis $type,
)*);
#[cfg(any($($($(all(), $(@ $PeekFrom)?)?)?)*))]
impl $crate::PeekFrom for $name {
fn peek_from(input: &$crate::Input) -> $crate::__::bool {
$crate::grammar!(@peek_first $name input $($type,)*)
}
}
#[cfg(any($($($(all(), $(@ $PopFrom)?)?)?)*))]
impl $crate::PopFrom for $name {
fn pop_from(input: &mut $crate::Input, errors: &mut $crate::Errors) -> $crate::__::Result<Self, ()> {
$crate::__::Result::Ok(Self (
$(<$type as $crate::PopFrom>::pop_from(input, errors)?,)*
))
}
}
$crate::grammar!($($tt)*);
};
(@peek_first $name:ident $input:ident $type:ty, $($rest:ty,)*) => (
<$type as $crate::PeekFrom>::peek_from($input)
);
(@peek_first $name:ident $input:ident) => (
::core::compile_error!($crate::__::concat!("To implement `PeekFrom` for `", $crate::__::stringify!($name), "`, at least one field is necessary."))
);
(@enum_doc []) => (
""
);
(@enum_doc [[$($type0:ty,)*] $([$($type:ty,)*])*]) => (
$crate::grammar!(@enum_doc [$([$($type,)*])*] [$("[`", $crate::__::stringify!($type0), "`] ", )*])
);
(@enum_doc [[$($type0:ty,)*] $([$($type:ty,)*])*] [$($output:tt)*]) => (
$crate::grammar!(@enum_doc [$([$($type,)*])*] [$($output)* "| ", $("[`", $crate::__::stringify!($type0), "`] ", )*])
);
(@enum_doc [] [$($output:tt)*]) => (
$crate::__::concat!($($output)*)
);
{$t:tt $($tt:tt)*} => {
::core::compile_error!($crate::__::concat!("Unexpected grammar input: ", $crate::__::stringify!($t $($tt)*)));
};
{} => {}; }
#[macro_export]
macro_rules! quote_into_mixed_site {
($span:expr, $root:expr, $tokens:expr, {$($tt:tt)*}$(,)?) => ({
let span: $crate::__::Span = $span.resolved_at($crate::__::Span::mixed_site());
let root: &$crate::__::TokenStream = $root;
let tokens = $tokens;
$( $crate::__::quote_one2!(span root tokens, $tt); )*
});
($span:expr, $root:expr, $tokens:expr, [$($tt:tt)*]$(,)?) => ({
let span: $crate::__::Span = $span.resolved_at($crate::__::Span::mixed_site());
let root: &$crate::__::TokenStream = $root;
let tokens = $tokens;
let mut enter_else = false;
$( $crate::__::quote_one!(span root tokens enter_else, $tt); )*
});
}
#[macro_export]
macro_rules! quote_into_with_exact_span {
($span:expr, $root:expr, $tokens:expr, {$($tt:tt)*}$(,)?) => ({
let span: $crate::__::Span = $span;
let root: &$crate::__::TokenStream = $root;
let tokens = $tokens;
$( $crate::__::quote_one2!(span root tokens, $tt); )*
});
($span:expr, $root:expr, $tokens:expr, [$($tt:tt)*]$(,)?) => ({
let span: $crate::__::Span = $span;
let root: &$crate::__::TokenStream = $root;
let tokens = $tokens;
let mut enter_else = false;
$( $crate::__::quote_one!(span root tokens enter_else, $tt); )*
});
}
#[macro_export]
macro_rules! quote_into_call_site {
($span:expr, $root:expr, $tokens:expr, {$($tt:tt)*}$(,)?) => ({
let span: $crate::__::Span = $span.resolved_at($crate::__::Span::call_site());
let root: &$crate::__::TokenStream = $root;
let tokens = $tokens;
$( $crate::__::quote_one2!(span root tokens, $tt); )*
});
($span:expr, $root:expr, $tokens:expr, [$($tt:tt)*]$(,)?) => ({
let span: $crate::__::Span = $span.resolved_at($crate::__::Span::call_site());
let root: &$crate::__::TokenStream = $root;
let tokens = $tokens;
let mut enter_else = false;
$( $crate::__::quote_one!(span root tokens enter_else, $tt); )*
});
}
#[macro_export]
macro_rules! raw_quote_into_mixed_site {
($span:expr, $tokens:expr, {$($tt:tt)*}$(,)?) => {{
let span: $crate::__::Span = $span.resolved_at($crate::__::Span::mixed_site());
$crate::__::raw($span, $tokens, $crate::__::stringify!($($tt)*));
}};
($span:expr, $tokens:expr, [$($tt:tt)*]$(,)?) => {{
let span: $crate::__::Span = $span.resolved_at($crate::__::Span::mixed_site());
$crate::__::raw($span, $tokens, $crate::__::stringify!($($tt)*));
}};
}
#[macro_export]
macro_rules! raw_quote_into_with_exact_span {
($span:expr, $tokens:expr, {$($tt:tt)*}$(,)?) => {
$crate::__::raw($span, $tokens, $crate::__::stringify!($($tt)*));
};
($span:expr, $tokens:expr, [$($tt:tt)*]$(,)?) => {
$crate::__::raw($span, $tokens, $crate::__::stringify!($($tt)*));
};
}
#[macro_export]
macro_rules! raw_quote_into_call_site {
($span:expr, $tokens:expr, {$($tt:tt)*}$(,)?) => {{
let span: $crate::__::Span = $span.resolved_at($crate::__::Span::call_site());
$crate::__::raw($span, $tokens, $crate::__::stringify!($($tt)*));
}};
($span:expr, $tokens:expr, [$($tt:tt)*]$(,)?) => {{
let span: $crate::__::Span = $span.resolved_at($crate::__::Span::call_site());
$crate::__::raw($span, $tokens, $crate::__::stringify!($($tt)*));
}};
}
#[doc(hidden)]
pub mod __ {
#![allow(missing_docs)]
use core::str::FromStr;
pub use core::{
clone::Clone, compile_error, concat, iter::Extend, primitive::bool, result::Result,
stringify,
};
use proc_macro2::{Delimiter, Group, Punct, Spacing};
pub use proc_macro2::{
Delimiter::{Brace, Bracket, Parenthesis},
Span, TokenStream, TokenTree,
};
use crate::IntoTokens;
pub use crate::{block_directive, quote_one, quote_one2, rust_statement_directive};
#[doc(hidden)]
#[macro_export]
macro_rules! quote_one {
($span:tt $root:tt $tokens:tt $enter_else:tt, {#paste $($expr:expr),*$(,)?}) => {
$( $crate::IntoTokens::into_tokens($expr, $root, $tokens); )*
};
($span:tt $root:tt $tokens:tt $enter_else:tt, {#raw $($tt:tt)*}) => {
$crate::__::raw($span, $tokens, $crate::__::stringify!($($tt)*));
};
($span:tt $root:tt $tokens:tt $enter_else:tt, {#error $($tt:tt)*}) => {{
$crate::IntoTokens::into_tokens($crate::__::Clone::clone($root), $root, $tokens);
$crate::__::raw($span, $tokens, "::core::compile_error!");
$crate::__::grouped($span, $crate::__::Parenthesis, $tokens, {
let mut inner_tokens = $crate::__::TokenStream::new();
let mut enter_else = false;
$( $crate::__::quote_one!($span $root (&mut inner_tokens) enter_else, $tt); )*
inner_tokens
});
$crate::__::raw($span, $tokens, ";");
}};
($span:tt $root:tt $tokens:tt $enter_else:tt, {#root}) => {
$crate::IntoTokens::into_tokens($crate::__::Clone::clone($root), $root, $tokens);
};
($span:tt $root:tt $tokens:tt $enter_else:tt, {#mixed_site $($tt:tt)*}) => {{
let span = $span.resolved_at($crate::__::Span::mixed_site());
$( $crate::__::quote_one!(span $root $tokens $enter_else, $tt); )*
}};
($span:tt $root:tt $tokens:tt $enter_else:tt, {#call_site $($tt:tt)*}) => {{
let span = $span.resolved_at($crate::__::Span::call_site());
$( $crate::__::quote_one!(span $root $tokens $enter_else, $tt); )*
}};
($span:tt $root:tt $tokens:tt $enter_else:tt, {#located_at $span2:expr, $($tt:tt)*}) => {{
let span = $span.located_at($span2);
$( $crate::__::quote_one!(span $root $tokens $enter_else, $tt); )*
}};
($span:tt $root:tt $tokens:tt $enter_else:tt, {#resolved_at $span2:expr, $($tt:tt)*}) => {{
let span = $span.resolved_at($span2);
$( $crate::__::quote_one!(span $root $tokens $enter_else, $tt); )*
}};
($_span:tt $root:tt $tokens:tt $enter_else:tt, {#with_exact_span $span:expr, $($tt:tt)*}) => {{
let span: $crate::__::Span = $span;
$( $crate::__::quote_one!(span $root $tokens $enter_else, $tt); )*
}};
($span:tt $root:tt $tokens:tt $enter_else:tt, {#let $pat:pat = $expr:expr $(, else { $($else:tt)* })?$(;)?}) => {
let $pat = $expr $(else { $($else)* })?;
};
($span:tt $root:tt $tokens:tt $enter_else:tt, {#break $label:lifetime $($expr:expr)?$(;)?}) => {
break $label $($expr)?;
};
($span:tt $root:tt $tokens:tt $enter_else:tt, {#break $($expr:expr)?$(;)?}) => {
break $($expr)?;
};
($span:tt $root:tt $tokens:tt $enter_else:tt, {#continue $($label:lifetime)?$(;)?}) => {
continue $($label)?;
};
($span:tt $root:tt $tokens:tt $enter_else:tt, {#return $($expr:expr)?$(;)?}) => {
return $($expr)?;
};
($span:tt $root:tt $tokens:tt $enter_else:tt, {# $(else $(@ $else:tt)?)? if $(let $pat:pat =)? $expr:expr, $($tt:tt)*}) => {
if true $(&& $enter_else $(@ $else)?)? {
if $(let $pat =)? $expr {
$enter_else = false;
let mut enter_else = false;
$( $crate::__::quote_one!($span $root $tokens enter_else, $tt); )*
} else {
$enter_else = true;
}
}
};
($span:tt $root:tt $tokens:tt $enter_else:tt, {#else, $($tt:tt)*}) => {
if $enter_else {
$enter_else = false;
let mut enter_else = false;
$( $crate::__::quote_one!($span $root $tokens enter_else, $tt); )*
}
};
($span:tt $root:tt $tokens:tt $enter_else:tt, {#match $expr:expr,
$(#![$($match_attr:tt)*])*
$(
$(#[$($arm_attr:tt)*])*
$pat:pat $(if $arm_expr:expr)? => {
$($tt:tt)*
}
)*
}) => {
$enter_else = false;
let mut enter_else = false;
match $expr {
$(#![$($match_attr)*])*
$(
$(#[$($arm_attr)*])*
$pat $(if $arm_expr)? => {
$( $crate::__::quote_one!($span $root $tokens enter_else, $tt); )*
}
)*
}
};
($span:tt $root:tt $tokens:tt $enter_else:tt, {#$($label:lifetime:)? $(loop $(@ $loop:tt)?)?, $($tt:tt)*}) => {
$enter_else = false;
$($label:)? $(loop $(@ $loop)?)? {
let mut enter_else = false;
$( $crate::__::quote_one!($span $root $tokens enter_else, $tt); )*
}
};
($span:tt $root:tt $tokens:tt $enter_else:tt, {#$($label:lifetime:)? for $pat:pat in $expr:expr, $($tt:tt)*}) => {
$enter_else = true;
$($label:)? for $pat in $expr {
$enter_else = false;
let mut enter_else = false;
$( $crate::__::quote_one!($span $root $tokens $enter_else, $tt); )*
}
};
($span:tt $root:tt $tokens:tt $enter_else:tt, {#$($label:lifetime:)? while $(let $pat:pat = )?$expr:expr, $($tt:tt)*}) => {
$enter_else = true;
$($label:)? while $(let $pat = )?$expr {
$enter_else = false;
let mut enter_else = false;
$( $crate::__::quote_one!($span $root $tokens $enter_else, $tt); )*
}
};
($span:tt $root:tt $tokens:tt $enter_else:tt, {#$reserved:ident $($tt:tt)*}) => {
$crate::__::compile_error!($crate::__::concat!("`{#", $crate::__::stringify!($reserved), "… }` is either reserved within Loess's quotes or its pattern wasn't matched. (Did you mean `{#paste ", $crate::__::stringify!($reserved), "… }` or `{#, #", $crate::__::stringify!($reserved), "… }`?)"));
};
($span:tt $root:tt $tokens:tt $enter_else:tt, {#$reserved:lifetime $($tt:tt)*}) => {
$crate::__::compile_error!($crate::__::concat!("`{#", $crate::__::stringify!($reserved), "… }` is either reserved within Loess's quotes or its pattern wasn't matched. (Did you mean `{#", $crate::__::stringify!($reserved), ":, … }` or `{#", $crate::__::stringify!($reserved), ": for … in …, … }`?)"));
};
($span:tt $root:tt $tokens:tt $_enter_else:tt, {$($tt:tt)*}) => {
$crate::__::grouped($span, $crate::__::Brace, $tokens, {
let mut inner_tokens = $crate::__::TokenStream::new();
let mut enter_else = false;
$( $crate::__::quote_one!($span $root (&mut inner_tokens) enter_else, $tt); )*
inner_tokens
});
};
($span:tt $root:tt $tokens:tt $enter_else:tt, [$($tt:tt)*]) => {
$crate::__::grouped($span, $crate::__::Bracket, $tokens, {
let mut inner_tokens = $crate::__::TokenStream::new();
let mut enter_else = false;
$( $crate::__::quote_one!($span $root (&mut inner_tokens) enter_else, $tt); )*
inner_tokens
});
};
($span:tt $root:tt $tokens:tt $enter_else:tt, ($($tt:tt)*)) => {
$crate::__::grouped($span, $crate::__::Parenthesis, $tokens, {
let mut inner_tokens = $crate::__::TokenStream::new();
let mut enter_else = false;
$( $crate::__::quote_one!($span $root (&mut inner_tokens) enter_else, $tt); )*
inner_tokens
});
};
($span:tt $root:tt $tokens:tt $enter_else:tt, $other:tt) => (
$crate::__::tt($span, $tokens, const { $crate::__::strip_dot($crate::__::stringify!($other .)) } );
);
($span:tt $root:tt $tokens:tt $enter_else:tt,) => {};
}
#[doc(hidden)]
#[macro_export]
macro_rules! quote_one2 {
($span:tt $root:tt $tokens:tt, {#()}) => { };
($span:tt $root:tt $tokens:tt, {#($expr:expr$(,)?)}) => {
$crate::IntoTokens::into_tokens($expr, $root, $tokens);
};
($span:tt $root:tt $tokens:tt, {#($($expr:expr),*$(,)?)}) => {
$crate::IntoTokens::into_tokens($crate::__::Paste(($($expr,)*)), $root, $tokens);
};
($span:tt $root:tt $tokens:tt, {#raw { $($tt:tt)* }}) => {
$crate::__::raw($span, $tokens, $crate::__::stringify!($($tt)*));
};
($span:tt $root:tt $tokens:tt, {#error { $($tt:tt)* }}) => {{
$crate::IntoTokens::into_tokens($crate::__::Clone::clone($root), $root, $tokens);
$crate::__::raw($span, $tokens, "::core::compile_error!");
$crate::__::grouped($span, $crate::__::Parenthesis, $tokens, {
let mut inner_tokens = $crate::__::TokenStream::new();
$( $crate::__::quote_one2!($span $root (&mut inner_tokens), $tt); )*
inner_tokens
});
}};
($span:tt $root:tt $tokens:tt, {#root}) => {
$crate::IntoTokens::into_tokens($crate::__::Clone::clone($root), $root, $tokens);
};
($span:tt $root:tt $tokens:tt, {#mixed_site { $($tt:tt)* }}) => {{
let span = $span.resolved_at($crate::__::Span::mixed_site());
$( $crate::__::quote_one2!(span $root $tokens, $tt); )*
}};
($span:tt $root:tt $tokens:tt, {#call_site { $($tt:tt)* }}) => {{
let span = $span.resolved_at($crate::__::Span::call_site());
$( $crate::__::quote_one2!(span $root $tokens, $tt); )*
}};
($span:tt $root:tt $tokens:tt, {#located_at($span2:expr) { $($tt:tt)* }}) => {{
let span = $span.located_at($span2);
$( $crate::__::quote_one2!(span $root $tokens, $tt); )*
}};
($span:tt $root:tt $tokens:tt, {#resolved_at($span2:expr) { $($tt:tt)* }}) => {{
let span = $span.resolved_at($span2);
$( $crate::__::quote_one2!(span $root $tokens, $tt); )*
}};
($_span:tt $root:tt $tokens:tt, {#with_exact_span($span:expr) { $($tt:tt)* }}) => {{
let span: $crate::__::Span = $span;
$( $crate::__::quote_one2!(span $root $tokens, $tt); )*
}};
($span:tt $root:tt $tokens:tt, {#let $($tt:tt)*}) => {
$crate::__::rust_statement_directive!([let] $($tt)*);
};
($span:tt $root:tt $tokens:tt, {#break $($tt:tt)*}) => {
$crate::__::rust_statement_directive!([break] $($tt)*);
};
($span:tt $root:tt $tokens:tt, {#continue $($tt:tt)*}) => {
$crate::__::rust_statement_directive!([continue] $($tt)*);
};
($span:tt $root:tt $tokens:tt, {#return $($tt:tt)*}) => {
$crate::__::rust_statement_directive!([return] $($tt)*);
};
($span:tt $root:tt $tokens:tt, {#{$($nested:tt)*} $($($unexpected:tt)+)?}) => {
{
$( $crate::__::quote_one2!($span $root $tokens, $nested); )*
}
$( $crate::__::compile_error!($crate::__::concat!("Unexpected tokens after `#{ … }`-directive:", $(" `", $crate::__::stringify!($unexpected), "`"),* )); )?
};
($span:tt $root:tt $tokens:tt, {#$ident:ident $($tt:tt)*}) => {
$crate::__::block_directive!($span $root $tokens, [] [$ident $ident] $([$tt $tt])*);
};
($span:tt $root:tt $tokens:tt, {#$label:lifetime $($tt:tt)*}) => {
$crate::__::block_directive!($span $root $tokens, [] [$label $label] $([$tt $tt])*);
};
($span:tt $root:tt $tokens:tt, {$($tt:tt)*}) => {
$crate::__::grouped($span, $crate::__::Brace, $tokens, {
let mut inner_tokens = $crate::__::TokenStream::new();
$( $crate::__::quote_one2!($span $root (&mut inner_tokens), $tt); )*
inner_tokens
});
};
($span:tt $root:tt $tokens:tt, [$($tt:tt)*]) => {
$crate::__::grouped($span, $crate::__::Bracket, $tokens, {
let mut inner_tokens = $crate::__::TokenStream::new();
$( $crate::__::quote_one2!($span $root (&mut inner_tokens), $tt); )*
inner_tokens
});
};
($span:tt $root:tt $tokens:tt, ($($tt:tt)*)) => {
$crate::__::grouped($span, $crate::__::Parenthesis, $tokens, {
let mut inner_tokens = $crate::__::TokenStream::new();
$( $crate::__::quote_one2!($span $root (&mut inner_tokens), $tt); )*
inner_tokens
});
};
($span:tt $root:tt $tokens:tt, $other:tt) => (
$crate::__::tt($span, $tokens, const { $crate::__::strip_dot($crate::__::stringify!($other .)) } );
);
($span:tt $root:tt $tokens:tt,) => {};
}
#[doc(hidden)]
#[macro_export]
macro_rules! rust_statement_directive {
([$($tt:tt)*] ;) => { $($tt)+; };
([$($tt:tt)*] ; $($rest:tt)+ ) => {
$($tt)+;
$crate::__::compile_error!($crate::__::concat!("Encountered tokens after `;` in statement directive:", $(" `", $crate::__::stringify!($rest), "`", )*));
};
([$($tt:tt)*] $next:tt $($rest:tt)+ ) => {
$crate::__::rust_statement_directive!([$($tt)* $next] $($rest)+);
};
([$($tt:tt)*] $incomplete:tt ) => {
$crate::__::compile_error!($crate::__::concat!("Incomplete statement directive: Expected `;` after this `", $crate::__::stringify!($incomplete), "`."));
};
([$($tt:tt)*]) => {
$crate::__::compile_error!($crate::__::concat!("Incomplete statement directive: Expected `;` after", $(" `", $crate::__::stringify!($tt), "`")*, "."));
};
}
#[doc(hidden)]
#[macro_export]
macro_rules! block_directive {
($span:tt $root:tt $tokens:tt, [[match $match:tt] $([$header:tt $_header:tt])*] [{ $(#![$($attr:tt)*])* $($(#[$($arm_attr:tt)*])* $pattern:pat $(if $guard_expression:expr)? => { $($nested:tt)* })* } $_:tt] $($([$unexpected:tt $_unexpected:tt])+)? ) => {
$match $($header)* {
$(#![$($attr)*])*
$(
$(#[$($arm_attr)*])*
$pattern $(if $guard_expression)? => {
$( $crate::__::quote_one2!($span $root $tokens, $nested); )*
}
)*
}
$( $crate::__::compile_error!($crate::__::concat!("Unexpected tokens after `#match`-directive:", $(" `", $crate::__::stringify!($unexpected), "`"),* )); )?
};
($span:tt $root:tt $tokens:tt, [[match $match:tt] $([$header:tt $_header:tt])*] [{ $($nested:tt)* } $_:tt] $($([$unexpected:tt $_unexpected:tt])+)? ) => {
$crate::__::compile_error!($crate::__::concat!("Unexpected `#match`-arm somewhere among here (make sure to use curly braces!):", $(" `", $crate::__::stringify!($nested), "`"),* ));
$( $crate::__::compile_error!($crate::__::concat!("Unexpected tokens after `#match`-directive:", $(" `", $crate::__::stringify!($unexpected), "`"),* )); )?
};
($span:tt $root:tt $tokens:tt, [$([$header:tt $_header:tt])*] [{ $($nested:tt)* } $_:tt] ) => {
$($header)* {
$( $crate::__::quote_one2!($span $root $tokens, $nested); )*
}
};
($span:tt $root:tt $tokens:tt, [$([$header:tt $_header:tt])*] [; $semi:tt] $($rest:tt)* ) => {
$crate::__::compile_error!($crate::__::concat!("Unexpected `", $crate::__::stringify!($semi), "` in block directive."));
};
($span:tt $root:tt $tokens:tt, [$($_header:tt)*] [{ $($_nested:tt)* } $_block:tt] [else $else:tt] [$label:lifetime $_label:tt] $($_rest:tt)* ) => {
$crate::__::compile_error!($crate::__::concat!("Unexpected `", $crate::__::stringify!($label), "` after `", $crate::__::stringify!($else), "`."));
};
($span:tt $root:tt $tokens:tt, [$([$label:lifetime $_label:tt] [: $colon:tt])? [if $if:tt] $([$header:tt $_header:tt])*] [{ $($nested:tt)* } $_block:tt] [else $else:tt] $($rest:tt)* ) => {
$($label $colon)? $if $($header)* {
$( $crate::__::quote_one2!($span $root $tokens, $nested); )*
} $else {
$crate::__::block_directive!($span $root $tokens, [] $($rest)*);
}
};
($span:tt $root:tt $tokens:tt, [$([$label:lifetime $_label:tt] [: $colon:tt])? [for $for:tt] $([$header:tt $_header:tt])*] [{ $($nested:tt)* } $_block:tt] [else $else:tt] $($rest:tt)* ) => {{
let mut skip_else = false;
$($label $colon)? $for $($header)* {
skip_else = true;
$( $crate::__::quote_one2!($span $root $tokens, $nested); )*
} if skip_else {} $else {
$crate::__::block_directive!($span $root $tokens, [] $($rest)*);
}
}};
($span:tt $root:tt $tokens:tt, [$([$label:lifetime $_label:tt] [: $colon:tt])? [while $while:tt] $([$header:tt $_header:tt])*] [{ $($nested:tt)* } $_block:tt] [else $else:tt] $($rest:tt)* ) => {{
let mut skip_else = false;
$($label $colon)? $while $($header)* {
skip_else = true;
$( $crate::__::quote_one2!($span $root $tokens, $nested); )*
} if skip_else {} $else {
$crate::__::block_directive!($span $root $tokens, [] $($rest)*);
}
}};
($span:tt $root:tt $tokens:tt, [$([$header:tt $_header:tt])*] [else $else:tt] $($rest:tt)* ) => {
$crate::__::compile_error!($crate::__::concat!("Unexpected `", $crate::__::stringify!($else), "`."));
};
($span:tt $root:tt $tokens:tt, [$($tt:tt)*] $next:tt $($rest:tt)* ) => {
$crate::__::block_directive!($span $root $tokens, [$($tt)* $next] $($rest)*);
};
($span:tt $root:tt $tokens:tt, [$($tt:tt)*] [$current:tt $_current:tt] ) => {
$crate::__::compile_error!($crate::__::concat!("Incomplete block directive: Expected `{` after this `", $crate::__::stringify!($current), "`."));
};
($span:tt $root:tt $tokens:tt, [] [$current:tt $_current:tt]) => {
$crate::__::compile_error!($crate::__::concat!("Incomplete block directive: Expected `{` after `", $crate::__::stringify!($current), "`."));
};
}
pub fn grouped(
span: Span,
delimiter: Delimiter,
tokens: &mut impl Extend<TokenTree>,
stream: TokenStream,
) {
let mut group = Group::new(delimiter, stream);
group.set_span(span);
tokens.extend([TokenTree::Group(group)]);
}
fn assign_span(
span: Span,
ts: impl IntoIterator<Item = TokenTree>,
) -> impl IntoIterator<Item = TokenTree> {
ts.into_iter().map(move |tt| match tt {
TokenTree::Group(group) => {
let group = Group::new(
group.delimiter(),
assign_span(span, group.stream()).into_iter().collect(),
);
TokenTree::Group(group)
}
mut tt @ (TokenTree::Ident(_) | TokenTree::Punct(_) | TokenTree::Literal(_)) => {
tt.set_span(span);
tt
}
})
}
pub fn raw(span: Span, tokens: &mut impl Extend<TokenTree>, stringified: &str) {
tokens.extend(assign_span(
span,
TokenStream::from_str(stringified).expect("Failed to parse stringified tokens, somehow. (Are you using the internal API from another crate? Please don't.)"),
))
}
pub const fn strip_dot(s: &str) -> &str {
s.split_at(s.len() - 1).0
}
pub fn tt(span: Span, tokens: &mut impl Extend<TokenTree>, stringified: &str) {
let mut ts = TokenStream::from_str(stringified).expect("Failed to parse stringified tokens, somehow. (Are you using the internal API from another crate? Please don't.)").into_iter().collect::<Box<[_]>>();
if let TokenTree::Punct(trailing_punct) = ts.last_mut().expect(
"always at least one token (Please don't use the internal API from other crates.)",
) {
*trailing_punct = Punct::new(
trailing_punct.as_char(),
match stringified
.chars()
.last()
.expect("always at least one char")
.is_ascii_whitespace()
{
true => Spacing::Alone,
false => Spacing::Joint,
},
)
}
tokens.extend(assign_span(span, ts));
}
pub struct Paste<T>(pub T);
impl<T0: IntoTokens, T1: IntoTokens> IntoTokens for Paste<(T0, T1)> {
fn into_tokens(self, root: &TokenStream, tokens: &mut impl Extend<TokenTree>) {
self.0.0.into_tokens(root, tokens);
self.0.1.into_tokens(root, tokens);
}
}
impl<T0: IntoTokens, T1: IntoTokens, T2: IntoTokens> IntoTokens for Paste<(T0, T1, T2)> {
fn into_tokens(self, root: &TokenStream, tokens: &mut impl Extend<TokenTree>) {
self.0.0.into_tokens(root, tokens);
self.0.1.into_tokens(root, tokens);
self.0.2.into_tokens(root, tokens);
}
}
impl<T0: IntoTokens, T1: IntoTokens, T2: IntoTokens, T3: IntoTokens> IntoTokens
for Paste<(T0, T1, T2, T3)>
{
fn into_tokens(self, root: &TokenStream, tokens: &mut impl Extend<TokenTree>) {
self.0.0.into_tokens(root, tokens);
self.0.1.into_tokens(root, tokens);
self.0.2.into_tokens(root, tokens);
self.0.3.into_tokens(root, tokens);
}
}
impl<T0: IntoTokens, T1: IntoTokens, T2: IntoTokens, T3: IntoTokens, T4: IntoTokens> IntoTokens
for Paste<(T0, T1, T2, T3, T4)>
{
fn into_tokens(self, root: &TokenStream, tokens: &mut impl Extend<TokenTree>) {
self.0.0.into_tokens(root, tokens);
self.0.1.into_tokens(root, tokens);
self.0.2.into_tokens(root, tokens);
self.0.3.into_tokens(root, tokens);
self.0.4.into_tokens(root, tokens);
}
}
impl<
T0: IntoTokens,
T1: IntoTokens,
T2: IntoTokens,
T3: IntoTokens,
T4: IntoTokens,
T5: IntoTokens,
> IntoTokens for Paste<(T0, T1, T2, T3, T4, T5)>
{
fn into_tokens(self, root: &TokenStream, tokens: &mut impl Extend<TokenTree>) {
self.0.0.into_tokens(root, tokens);
self.0.1.into_tokens(root, tokens);
self.0.2.into_tokens(root, tokens);
self.0.3.into_tokens(root, tokens);
self.0.4.into_tokens(root, tokens);
self.0.5.into_tokens(root, tokens);
}
}
impl<
T0: IntoTokens,
T1: IntoTokens,
T2: IntoTokens,
T3: IntoTokens,
T4: IntoTokens,
T5: IntoTokens,
T6: IntoTokens,
> IntoTokens for Paste<(T0, T1, T2, T3, T4, T5, T6)>
{
fn into_tokens(self, root: &TokenStream, tokens: &mut impl Extend<TokenTree>) {
self.0.0.into_tokens(root, tokens);
self.0.1.into_tokens(root, tokens);
self.0.2.into_tokens(root, tokens);
self.0.3.into_tokens(root, tokens);
self.0.4.into_tokens(root, tokens);
self.0.5.into_tokens(root, tokens);
self.0.6.into_tokens(root, tokens);
}
}
impl<
T0: IntoTokens,
T1: IntoTokens,
T2: IntoTokens,
T3: IntoTokens,
T4: IntoTokens,
T5: IntoTokens,
T6: IntoTokens,
T7: IntoTokens,
> IntoTokens for Paste<(T0, T1, T2, T3, T4, T5, T6, T7)>
{
fn into_tokens(self, root: &TokenStream, tokens: &mut impl Extend<TokenTree>) {
self.0.0.into_tokens(root, tokens);
self.0.1.into_tokens(root, tokens);
self.0.2.into_tokens(root, tokens);
self.0.3.into_tokens(root, tokens);
self.0.4.into_tokens(root, tokens);
self.0.5.into_tokens(root, tokens);
self.0.6.into_tokens(root, tokens);
self.0.7.into_tokens(root, tokens);
}
}
impl<
T0: IntoTokens,
T1: IntoTokens,
T2: IntoTokens,
T3: IntoTokens,
T4: IntoTokens,
T5: IntoTokens,
T6: IntoTokens,
T7: IntoTokens,
T8: IntoTokens,
> IntoTokens for Paste<(T0, T1, T2, T3, T4, T5, T6, T7, T8)>
{
fn into_tokens(self, root: &TokenStream, tokens: &mut impl Extend<TokenTree>) {
self.0.0.into_tokens(root, tokens);
self.0.1.into_tokens(root, tokens);
self.0.2.into_tokens(root, tokens);
self.0.3.into_tokens(root, tokens);
self.0.4.into_tokens(root, tokens);
self.0.5.into_tokens(root, tokens);
self.0.6.into_tokens(root, tokens);
self.0.7.into_tokens(root, tokens);
self.0.8.into_tokens(root, tokens);
}
}
impl<
T0: IntoTokens,
T1: IntoTokens,
T2: IntoTokens,
T3: IntoTokens,
T4: IntoTokens,
T5: IntoTokens,
T6: IntoTokens,
T7: IntoTokens,
T8: IntoTokens,
T9: IntoTokens,
> IntoTokens for Paste<(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9)>
{
fn into_tokens(self, root: &TokenStream, tokens: &mut impl Extend<TokenTree>) {
self.0.0.into_tokens(root, tokens);
self.0.1.into_tokens(root, tokens);
self.0.2.into_tokens(root, tokens);
self.0.3.into_tokens(root, tokens);
self.0.4.into_tokens(root, tokens);
self.0.5.into_tokens(root, tokens);
self.0.6.into_tokens(root, tokens);
self.0.7.into_tokens(root, tokens);
self.0.8.into_tokens(root, tokens);
self.0.9.into_tokens(root, tokens);
}
}
impl<
T0: IntoTokens,
T1: IntoTokens,
T2: IntoTokens,
T3: IntoTokens,
T4: IntoTokens,
T5: IntoTokens,
T6: IntoTokens,
T7: IntoTokens,
T8: IntoTokens,
T9: IntoTokens,
T10: IntoTokens,
> IntoTokens for Paste<(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10)>
{
fn into_tokens(self, root: &TokenStream, tokens: &mut impl Extend<TokenTree>) {
self.0.0.into_tokens(root, tokens);
self.0.1.into_tokens(root, tokens);
self.0.2.into_tokens(root, tokens);
self.0.3.into_tokens(root, tokens);
self.0.4.into_tokens(root, tokens);
self.0.5.into_tokens(root, tokens);
self.0.6.into_tokens(root, tokens);
self.0.7.into_tokens(root, tokens);
self.0.8.into_tokens(root, tokens);
self.0.9.into_tokens(root, tokens);
self.0.10.into_tokens(root, tokens);
}
}
impl<
T0: IntoTokens,
T1: IntoTokens,
T2: IntoTokens,
T3: IntoTokens,
T4: IntoTokens,
T5: IntoTokens,
T6: IntoTokens,
T7: IntoTokens,
T8: IntoTokens,
T9: IntoTokens,
T10: IntoTokens,
T11: IntoTokens,
> IntoTokens for Paste<(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11)>
{
fn into_tokens(self, root: &TokenStream, tokens: &mut impl Extend<TokenTree>) {
self.0.0.into_tokens(root, tokens);
self.0.1.into_tokens(root, tokens);
self.0.2.into_tokens(root, tokens);
self.0.3.into_tokens(root, tokens);
self.0.4.into_tokens(root, tokens);
self.0.5.into_tokens(root, tokens);
self.0.6.into_tokens(root, tokens);
self.0.7.into_tokens(root, tokens);
self.0.8.into_tokens(root, tokens);
self.0.9.into_tokens(root, tokens);
self.0.10.into_tokens(root, tokens);
self.0.11.into_tokens(root, tokens);
}
}
}