#![cfg_attr(not(feature = "std"), no_std)]
#[macro_export]
macro_rules! macro_attr {
($($item:tt)*) => {
macro_attr_impl! { $($item)* }
};
}
#[doc(hidden)]
#[macro_export]
macro_rules! macro_attr_impl {
(
$(#[$($attrs:tt)*])*
const $($it:tt)*
) => {
macro_attr_impl! {
@split_attrs
($(#[$($attrs)*],)*), (), (),
(const $($it)*)
}
};
(
$(#[$($attrs:tt)*])*
enum $($it:tt)*
) => {
macro_attr_impl! {
@split_attrs
($(#[$($attrs)*],)*), (), (),
(enum $($it)*)
}
};
(
$(#[$($attrs:tt)*])*
extern $($it:tt)*
) => {
macro_attr_impl! {
@split_attrs
($(#[$($attrs)*],)*), (), (),
(extern $($it)*)
}
};
(
$(#[$($attrs:tt)*])*
fn $($it:tt)*
) => {
macro_attr_impl! {
@split_attrs
($(#[$($attrs)*],)*), (), (),
(fn $($it)*)
}
};
(
$(#[$($attrs:tt)*])*
impl $($it:tt)*
) => {
macro_attr_impl! {
@split_attrs
($(#[$($attrs)*],)*), (), (),
(impl $($it)*)
}
};
(
$(#[$($attrs:tt)*])*
mod $($it:tt)*
) => {
macro_attr_impl! {
@split_attrs
($(#[$($attrs)*],)*), (), (),
(mod $($it)*)
}
};
(
$(#[$($attrs:tt)*])*
pub $($it:tt)*
) => {
macro_attr_impl! {
@split_attrs
($(#[$($attrs)*],)*), (), (),
(pub $($it)*)
}
};
(
$(#[$($attrs:tt)*])*
static $($it:tt)*
) => {
macro_attr_impl! {
@split_attrs
($(#[$($attrs)*],)*), (), (),
(static $($it)*)
}
};
(
$(#[$($attrs:tt)*])*
struct $($it:tt)*
) => {
macro_attr_impl! {
@split_attrs
($(#[$($attrs)*],)*), (), (),
(struct $($it)*)
}
};
(
$(#[$($attrs:tt)*])*
trait $($it:tt)*
) => {
macro_attr_impl! {
@split_attrs
($(#[$($attrs)*],)*), (), (),
(trait $($it)*)
}
};
(
$(#[$($attrs:tt)*])*
type $($it:tt)*
) => {
macro_attr_impl! {
@split_attrs
($(#[$($attrs)*],)*), (), (),
(type $($it)*)
}
};
(
$(#[$($attrs:tt)*])*
use $($it:tt)*
) => {
macro_attr_impl! {
@split_attrs
($(#[$($attrs)*],)*), (), (),
(use $($it)*)
}
};
(
@split_attrs
(),
$non_derives:tt,
$derives:tt,
$it:tt
) => {
macro_attr_impl! {
@split_derive_attrs
{ $non_derives, $it },
$derives,
(),
()
}
};
(
@split_attrs
(#[derive($($new_drvs:tt)*)], $(#[$($attrs:tt)*],)*),
$non_derives:tt,
($($derives:tt)*),
$it:tt
) => {
macro_attr_impl! {
@split_attrs
($(#[$($attrs)*],)*),
$non_derives,
($($derives)* $($new_drvs)*,),
$it
}
};
(
@split_attrs
(#[$mac_attr:ident!], $(#[$($attrs:tt)*],)*),
$non_derives:tt,
$derives:tt,
($($it:tt)*)
) => {
$mac_attr! {
(),
then (macro_attr_impl! {
@split_attrs_resume
$non_derives,
$derives,
}),
$(#[$($attrs)*])*
$($it)*
}
};
(
@split_attrs
(#[$mac_attr:ident!($($attr_args:tt)*)], $(#[$($attrs:tt)*],)*),
$non_derives:tt,
$derives:tt,
($($it:tt)*)
) => {
$mac_attr! {
($($attr_args)*),
then (macro_attr_impl! {
@split_attrs_resume
$non_derives,
$derives,
}),
$(#[$($attrs)*])*
$($it)*
}
};
(
@split_attrs
(#[$mac_attr:ident~!], $(#[$($attrs:tt)*],)*),
($($non_derives:tt)*),
$derives:tt,
($($it:tt)*)
) => {
macro_attr_if_proc_macros! {
proc_macros: {
macro_attr_impl! {
@split_attrs
($(#[$($attrs)*],)*),
($($non_derives)* #[$mac_attr],),
$derives,
$($it)*
}
}
fallback: {
$mac_attr! {
(),
then (macro_attr_impl! {
@split_attrs_resume
($($non_derives)*),
$derives,
}),
$(#[$($attrs)*])*
$($it)*
}
}
}
};
(
@split_attrs
(#[$mac_attr:ident~!($($attr_args:tt)*)], $(#[$($attrs:tt)*],)*),
($($non_derives:tt)*),
$derives:tt,
($($it:tt)*)
) => {
macro_attr_if_proc_macros! {
proc_macros: {
macro_attr_impl! {
@split_attrs
($(#[$($attrs)*],)*),
($($non_derives)* #[$mac_attr($($attr_args)*)],),
$derives,
$($it)*
}
}
fallback: {
$mac_attr! {
($($attr_args)*),
then (macro_attr_impl! {
@split_attrs_resume
($($non_derives)*),
$derives,
}),
$(#[$($attrs)*])*
$($it)*
}
}
}
};
(
@split_attrs
(#[$new_attr:meta], $(#[$($attrs:tt)*],)*),
($($non_derives:tt)*),
$derives:tt,
$it:tt
) => {
macro_attr_impl! {
@split_attrs
($(#[$($attrs)*],)*),
($($non_derives)* #[$new_attr],),
$derives,
$it
}
};
(
@split_attrs_resume
$non_derives:tt,
$derives:tt,
$(#[$($attrs:tt)*])*
const $($it:tt)*
) => {
macro_attr_impl! {
@split_attrs
($(#[$($attrs)*],)*),
$non_derives,
$derives,
(const $($it)*)
}
};
(
@split_attrs_resume
$non_derives:tt,
$derives:tt,
$(#[$($attrs:tt)*])*
enum $($it:tt)*
) => {
macro_attr_impl! {
@split_attrs
($(#[$($attrs)*],)*),
$non_derives,
$derives,
(enum $($it)*)
}
};
(
@split_attrs_resume
$non_derives:tt,
$derives:tt,
$(#[$($attrs:tt)*])*
extern $($it:tt)*
) => {
macro_attr_impl! {
@split_attrs
($(#[$($attrs)*],)*),
$non_derives,
$derives,
(extern $($it)*)
}
};
(
@split_attrs_resume
$non_derives:tt,
$derives:tt,
$(#[$($attrs:tt)*])*
fn $($it:tt)*
) => {
macro_attr_impl! {
@split_attrs
($(#[$($attrs)*],)*),
$non_derives,
$derives,
(fn $($it)*)
}
};
(
@split_attrs_resume
$non_derives:tt,
$derives:tt,
$(#[$($attrs:tt)*])*
impl $($it:tt)*
) => {
macro_attr_impl! {
@split_attrs
($(#[$($attrs)*],)*),
$non_derives,
$derives,
(impl $($it)*)
}
};
(
@split_attrs_resume
$non_derives:tt,
$derives:tt,
$(#[$($attrs:tt)*])*
mod $($it:tt)*
) => {
macro_attr_impl! {
@split_attrs
($(#[$($attrs)*],)*),
$non_derives,
$derives,
(mod $($it)*)
}
};
(
@split_attrs_resume
$non_derives:tt,
$derives:tt,
$(#[$($attrs:tt)*])*
pub $($it:tt)*
) => {
macro_attr_impl! {
@split_attrs
($(#[$($attrs)*],)*),
$non_derives,
$derives,
(pub $($it)*)
}
};
(
@split_attrs_resume
$non_derives:tt,
$derives:tt,
$(#[$($attrs:tt)*])*
static $($it:tt)*
) => {
macro_attr_impl! {
@split_attrs
($(#[$($attrs)*],)*),
$non_derives,
$derives,
(static $($it)*)
}
};
(
@split_attrs_resume
$non_derives:tt,
$derives:tt,
$(#[$($attrs:tt)*])*
struct $($it:tt)*
) => {
macro_attr_impl! {
@split_attrs
($(#[$($attrs)*],)*),
$non_derives,
$derives,
(struct $($it)*)
}
};
(
@split_attrs_resume
$non_derives:tt,
$derives:tt,
$(#[$($attrs:tt)*])*
trait $($it:tt)*
) => {
macro_attr_impl! {
@split_attrs
($(#[$($attrs)*],)*),
$non_derives,
$derives,
(trait $($it)*)
}
};
(
@split_attrs_resume
$non_derives:tt,
$derives:tt,
$(#[$($attrs:tt)*])*
type $($it:tt)*
) => {
macro_attr_impl! {
@split_attrs
($(#[$($attrs)*],)*),
$non_derives,
$derives,
(type $($it)*)
}
};
(
@split_attrs_resume
$non_derives:tt,
$derives:tt,
$(#[$($attrs:tt)*])*
use $($it:tt)*
) => {
macro_attr_impl! {
@split_attrs
($(#[$($attrs)*],)*),
$non_derives,
$derives,
(use $($it)*)
}
};
(@split_derive_attrs
{ ($(#[$($non_derives:tt)*],)*), ($($it:tt)*) },
($(,)*), (), ($($user_drvs:tt)*)
) => {
macro_attr_impl! {
@as_item
$(#[$($non_derives)*])*
$($it)*
}
macro_attr_impl! {
@expand_user_drvs
($($user_drvs)*), ($($it)*)
}
};
(@split_derive_attrs
{ ($(#[$($non_derives:tt)*],)*), ($($it:tt)*) },
($(,)*), ($($bi_drvs:ident,)+), ($($user_drvs:tt)*)
) => {
macro_attr_impl! {
@as_item
#[derive($($bi_drvs,)+)]
$(#[$($non_derives)*])*
$($it)*
}
macro_attr_impl! {
@expand_user_drvs
($($user_drvs)*), ($($it)*)
}
};
(@split_derive_attrs
$fixed:tt,
(,, $($tail:tt)*), $bi_drvs:tt, $user_drvs:tt
) => {
macro_attr_impl! {
@split_derive_attrs
$fixed, ($($tail)*), $bi_drvs, $user_drvs
}
};
(@split_derive_attrs
$fixed:tt,
(, $($tail:tt)*), $bi_drvs:tt, $user_drvs:tt
) => {
macro_attr_impl! {
@split_derive_attrs
$fixed, ($($tail)*), $bi_drvs, $user_drvs
}
};
(@split_derive_attrs
$fixed:tt,
($new_user:ident ! ($($new_user_args:tt)*), $($tail:tt)*), $bi_drvs:tt, ($($user_drvs:tt)*)
) => {
macro_attr_impl! {
@split_derive_attrs
$fixed, ($($tail)*), $bi_drvs, ($($user_drvs)* $new_user($($new_user_args)*),)
}
};
(@split_derive_attrs
$fixed:tt,
($new_user:ident !, $($tail:tt)*), $bi_drvs:tt, ($($user_drvs:tt)*)
) => {
macro_attr_impl! {
@split_derive_attrs
$fixed, ($($tail)*), $bi_drvs, ($($user_drvs)* $new_user(),)
}
};
(@split_derive_attrs
$fixed:tt,
($new_drv:ident ~!, $($tail:tt)*), ($($bi_drvs:ident,)*), ($($user_drvs:tt)*)
) => {
macro_attr_if_proc_macros! {
proc_macros: {
macro_attr_impl! {
@split_derive_attrs
$fixed,
($($tail)*),
($($bi_drvs,)* $new_drv,),
($($user_drvs)*)
}
}
fallback: {
macro_attr_impl! {
@split_derive_attrs
$fixed,
($($tail)*),
($($bi_drvs,)*),
($($user_drvs)* $new_drv(),)
}
}
}
};
(@split_derive_attrs
$fixed:tt,
($drv:ident, $($tail:tt)*), ($($bi_drvs:ident,)*), $user_drvs:tt
) => {
macro_attr_impl! {
@split_derive_attrs
$fixed,
($($tail)*), ($($bi_drvs,)* $drv,), $user_drvs
}
};
(@expand_user_drvs
(), ($($it:tt)*)
) => {};
(@expand_user_drvs
($user_drv:ident $arg:tt, $($tail:tt)*), ($($it:tt)*)
) => {
$user_drv! { $arg $($it)* }
macro_attr_impl! {
@expand_user_drvs
($($tail)*), ($($it)*)
}
};
(@as_item $($i:item)*) => {$($i)*};
}
#[macro_export]
macro_rules! macro_attr_callback {
(
($cb:ident ! { $($cb_fixed:tt)* }),
$($args:tt)*
) => {
$cb! { $($cb_fixed)* $($args)* }
};
(
($cb:ident ! [ $($cb_fixed:tt)* ]),
$($args:tt)*
) => {
$cb! [ $($cb_fixed)* $($args)* ]
};
(
($cb:ident ! ( $($cb_fixed:tt)* )),
$($args:tt)*
) => {
$cb! ( $($cb_fixed)* $($args)* )
};
}
#[doc(hidden)]
#[macro_export]
#[cfg(feature="unstable-macros-1-1")]
macro_rules! macro_attr_if_proc_macros {
(
proc_macros: { $($items:item)* }
fallback: $_ignore:tt
) => {
$($items)*
};
}
#[doc(hidden)]
#[macro_export]
#[cfg(not(feature="unstable-macros-1-1"))]
macro_rules! macro_attr_if_proc_macros {
(
proc_macros: $_ignore:tt
fallback: { $($items:item)* }
) => {
$($items)*
};
}