#![doc = include_str!(concat!(env!("CARGO_MANIFEST_DIR"), "/", "README.md"))]
#[macro_export]
macro_rules! proc_macro {
($name:ident -> use $func:ident) => {
#[proc_macro]
pub fn $name(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
$func(input)
}
};
($name:ident -> $func:ident) => {
$crate::proc_macro!($name -> mod $func);
};
($name:ident -> use $module:ident :: $func:ident) => {
#[proc_macro]
pub fn $name(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
$module::$func(input)
}
};
($name:ident -> mod $module:ident :: $func:ident) => {
mod $module;
$crate::proc_macro!($name -> use $module :: $func);
};
($name:ident -> $module:ident :: $func:ident) => {
$crate::proc_macro!($name -> mod $module :: $func);
};
($name:ident -> use $($module:ident)::+ :: $func:ident) => {
#[proc_macro]
pub fn $name(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
$($module::)+$func(input)
}
};
($name:ident -> mod $first:ident $(:: $rest:ident)+ :: $func:ident) => {
mod $first;
$crate::proc_macro!($name -> use $first$(::$rest)+ :: $func);
};
($name:ident -> $first:ident $(:: $rest:ident)+ :: $func:ident) => {
$crate::proc_macro!($name -> mod $first $(:: $rest)+ :: $func);
};
($name:ident -> $path:literal :: $func:ident) => {
#[proc_macro]
pub fn $name(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
#[path = $path]
mod __inner;
__inner::$func(input)
}
};
($name:ident -> @$path:literal :: $func:ident) => {
#[proc_macro]
pub fn $name(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
mod __inner {
include!(concat!(env!("CARGO_MANIFEST_DIR"), "/", $path));
}
__inner::$func(input)
}
};
}
#[macro_export]
macro_rules! attr_macro {
($name:ident -> $func:ident) => {
#[proc_macro_attribute]
pub fn $name(attr: proc_macro::TokenStream, item: proc_macro::TokenStream) -> proc_macro::TokenStream {
$func(attr, item)
}
};
($name:ident -> use $module:ident :: $func:ident) => {
#[proc_macro_attribute]
pub fn $name(attr: proc_macro::TokenStream, item: proc_macro::TokenStream) -> proc_macro::TokenStream {
$module::$func(attr, item)
}
};
($name:ident -> mod $module:ident :: $func:ident) => {
mod $module;
$crate::attr_macro!($name -> use $module :: $func);
};
($name:ident -> $module:ident :: $func:ident) => {
$crate::attr_macro!($name -> mod $module :: $func);
};
($name:ident -> use $($module:ident)::+ :: $func:ident) => {
#[proc_macro_attribute]
pub fn $name(attr: proc_macro::TokenStream, item: proc_macro::TokenStream) -> proc_macro::TokenStream {
$($module::)+$func(attr, item)
}
};
($name:ident -> mod $first:ident $(:: $rest:ident)+ :: $func:ident) => {
mod $first;
$crate::attr_macro!($name -> use $first$(::$rest)+ :: $func);
};
($name:ident -> $first:ident $(:: $rest:ident)+ :: $func:ident) => {
$crate::attr_macro!($name -> mod $first $(:: $rest)+ :: $func);
};
($name:ident -> $path:literal :: $func:ident) => {
#[proc_macro_attribute]
pub fn $name(attr: proc_macro::TokenStream, item: proc_macro::TokenStream) -> proc_macro::TokenStream {
#[path = $path]
mod __inner;
__inner::$func(attr, item)
}
};
($name:ident -> @$path:literal :: $func:ident) => {
#[proc_macro_attribute]
pub fn $name(attr: proc_macro::TokenStream, item: proc_macro::TokenStream) -> proc_macro::TokenStream {
mod __inner {
include!(concat!(env!("CARGO_MANIFEST_DIR"), "/", $path));
}
__inner::$func(attr, item)
}
};
}
#[macro_export]
macro_rules! derive_macro {
(($name:ident $(, $attr:tt)*) -> use $func:ident) => {
#[allow(non_snake_case)]
#[proc_macro_derive($name $(, $attr)*)]
pub fn $name(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
$func(input)
}
};
(($name:ident, attributes($($attr:ident),*)) -> use $func:ident) => {
#[allow(non_snake_case)]
#[proc_macro_derive($name, attributes($($attr),*))]
pub fn $name(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
$func(input)
}
};
(($name:ident $(, $attr:tt)*) -> use $module:ident :: $func:ident) => {
#[allow(non_snake_case)]
#[proc_macro_derive($name $(, $attr)*)]
pub fn $name(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
$module::$func(input)
}
};
(($name:ident, attributes($($attr:ident),*)) -> use $module:ident :: $func:ident) => {
#[allow(non_snake_case)]
#[proc_macro_derive($name, attributes($($attr),*))]
pub fn $name(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
$module::$func(input)
}
};
(($name:ident $(, $attr:tt)*) -> use $($module:ident)::+ :: $func:ident) => {
#[allow(non_snake_case)]
#[proc_macro_derive($name $(, $attr)*)]
pub fn $name(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
$($module::)+$func(input)
}
};
(($name:ident, attributes($($attr:ident),*)) -> use $($module:ident)::+ :: $func:ident) => {
#[allow(non_snake_case)]
#[proc_macro_derive($name, attributes($($attr),*))]
pub fn $name(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
$($module::)+$func(input)
}
};
(($name:ident $(, $attr:tt)*) -> $func:ident) => {
$crate::derive_macro!(($name $(, $attr)*) -> use $func);
};
(($name:ident, attributes($($attr:tt),*)) -> $func:ident) => {
$crate::derive_macro!(($name, attributes($($attr),*)) -> use $func);
};
(($name:ident $(, $attr:tt)*) -> mod $module:ident :: $func:ident) => {
mod $module;
$crate::derive_macro!(($name $(, $attr)*) -> use $module :: $func);
};
(($name:ident, attributes($($attr:tt),*)) -> mod $module:ident :: $func:ident) => {
mod $module;
$crate::derive_macro!(($name, attributes($($attr),*))-> use $module :: $func);
};
(($name:ident $(, $attr:tt)*) -> $module:ident :: $func:ident) => {
$crate::derive_macro!(($name $(, $attr)*) -> mod $module :: $func);
};
(($name:ident, attributes($($attr:tt),*)) -> $module:ident :: $func:ident) => {
$crate::derive_macro!(($name, attributes($($attr),*))-> mod $module :: $func);
};
(($name:ident $(, $attr:tt)*) -> mod $first:ident $(:: $rest:ident)+ :: $func:ident) => {
mod $first;
$crate::derive_macro!(($name $(, $attr)*) -> use $first$(::$rest)+ :: $func);
};
(($name:ident, attributes($($attr:tt),*)) -> mod $first:ident $(:: $rest:ident)+ :: $func:ident) => {
mod $first;
$crate::derive_macro!(($name, attributes($($attr),*)) -> use $first$(::$rest)+ :: $func);
};
(($name:ident $(, $attr:tt)*) -> $first:ident $(:: $rest:ident)+ :: $func:ident) => {
$crate::derive_macro!(($name $(, $attr)*) -> mod $first $(:: $rest)+ :: $func);
};
(($name:ident, attributes($($attr:tt),*)) -> $first:ident $(:: $rest:ident)+ :: $func:ident) => {
$crate::derive_macro!(($name, attributes($($attr),*)) -> mod $first $(:: $rest)+ :: $func);
};
(($name:ident $(, $attr:tt)*) -> $path:literal :: $func:ident) => {
#[allow(non_snake_case)]
#[proc_macro_derive($name $(, $attr)*)]
pub fn $name(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
#[path = $path]
mod __inner;
__inner::$func(input)
}
};
(($name:ident $(, $attr:tt)*) -> @$path:literal :: $func:ident) => {
#[allow(non_snake_case)]
#[proc_macro_derive($name $(, $attr)*)]
pub fn $name(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
mod __inner {
include!(concat!(env!("CARGO_MANIFEST_DIR"), "/", $path));
}
__inner::$func(input)
}
};
}
#[macro_export]
macro_rules! macros {
() => {};
(function -> $module:ident :: $func:ident , $($tail:tt)*) => {
$crate::proc_macro!($func -> $module::$func);
$crate::macros!($($tail)*);
};
(function -> $func:ident , $($tail:tt)*) => {
$crate::proc_macro!($func -> $func);
$crate::macros!($($tail)*);
};
(function -> @$path:literal :: $func:ident , $($tail:tt)*) => {
$crate::proc_macro!($func -> @$path::$func);
$crate::macros!($($tail)*);
};
(function($name:ident) -> $func:ident , $($tail:tt)*) => {
$crate::proc_macro!($name -> $func);
$crate::macros!($($tail)*);
};
(function($name:ident) -> $module:ident :: $func:ident , $($tail:tt)*) => {
$crate::proc_macro!($name -> $module::$func);
$crate::macros!($($tail)*);
};
(function($name:ident) -> @$path:literal :: $func:ident , $($tail:tt)*) => {
$crate::proc_macro!($name -> @$path::$func);
$crate::macros!($($tail)*);
};
(function($name:ident) -> use $func:ident , $($tail:tt)*) => {
$crate::proc_macro!($name -> use $func);
$crate::macros!($($tail)*);
};
(function($name:ident) -> use $module:ident :: $func:ident , $($tail:tt)*) => {
$crate::proc_macro!($name -> use $module::$func);
$crate::macros!($($tail)*);
};
(function($name:ident) -> mod $func:ident , $($tail:tt)*) => {
$crate::proc_macro!($name -> mod $func);
$crate::macros!($($tail)*);
};
(function($name:ident) -> mod $module:ident :: $func:ident , $($tail:tt)*) => {
$crate::proc_macro!($name -> mod $module::$func);
$crate::macros!($($tail)*);
};
(function($name:ident) -> $path:literal :: $func:ident , $($tail:tt)*) => {
$crate::proc_macro!($name -> $path::$func);
$crate::macros!($($tail)*);
};
(attribute -> $func:ident , $($tail:tt)*) => {
$crate::attr_macro!($func -> $func);
$crate::macros!($($tail)*);
};
(attribute -> $module:ident :: $func:ident , $($tail:tt)*) => {
$crate::attr_macro!($func -> $module::$func);
$crate::macros!($($tail)*);
};
(attribute -> @$path:literal :: $func:ident , $($tail:tt)*) => {
$crate::attr_macro!($func -> @$path::$func);
$crate::macros!($($tail)*);
};
(attribute($name:ident) -> $func:ident , $($tail:tt)*) => {
$crate::attr_macro!($name -> $func);
$crate::macros!($($tail)*);
};
(attribute($name:ident) -> $module:ident :: $func:ident , $($tail:tt)*) => {
$crate::attr_macro!($name -> $module::$func);
$crate::macros!($($tail)*);
};
(attribute($name:ident) -> @$path:literal :: $func:ident , $($tail:tt)*) => {
$crate::attr_macro!($name -> @$path::$func);
$crate::macros!($($tail)*);
};
(attribute($name:ident) -> use $func:ident , $($tail:tt)*) => {
$crate::attr_macro!($name -> use $func);
$crate::macros!($($tail)*);
};
(attribute($name:ident) -> use $module:ident :: $func:ident , $($tail:tt)*) => {
$crate::attr_macro!($name -> use $module::$func);
$crate::macros!($($tail)*);
};
(attribute($name:ident) -> mod $func:ident , $($tail:tt)*) => {
$crate::attr_macro!($name -> mod $func);
$crate::macros!($($tail)*);
};
(attribute($name:ident) -> mod $module:ident :: $func:ident , $($tail:tt)*) => {
$crate::attr_macro!($name -> mod $module::$func);
$crate::macros!($($tail)*);
};
(derive($name:ident, attributes($($attr:ident),*)) -> $module:ident :: $func:ident , $($tail:tt)*) => {
$crate::derive_macro!(($name, attributes($($attr),*)) -> $module::$func);
$crate::macros!($($tail)*);
};
(derive($name:ident, attributes($($attr:ident),*)) -> $module:ident :: $func:ident) => {
$crate::derive_macro!(($name, attributes($($attr),*)) -> $module::$func);
};
(derive($name:ident, attributes($($attr:ident),+)) -> $module:ident :: $func:ident , $($tail:tt)*) => {
$crate::derive_macro!(($name, attributes($($attr),+)) -> $module::$func);
$crate::macros!($($tail)*);
};
(derive($name:ident, attributes($($attr:ident),+)) -> use $module:ident :: $func:ident , $($tail:tt)*) => {
$crate::derive_macro!(($name, attributes($($attr),+)) -> use $module::$func);
$crate::macros!($($tail)*);
};
(derive($name:ident, attributes($($attr:ident),+)) -> mod $module:ident :: $func:ident , $($tail:tt)*) => {
$crate::derive_macro!(($name, attributes($($attr),+)) -> mod $module::$func);
$crate::macros!($($tail)*);
};
(derive($name:ident) -> $func:ident , $($tail:tt)*) => {
$crate::derive_macro!(($name) -> $func);
$crate::macros!($($tail)*);
};
(derive($name:ident) -> $module:ident :: $func:ident , $($tail:tt)*) => {
$crate::derive_macro!(($name) -> $module::$func);
$crate::macros!($($tail)*);
};
(derive($name:ident) -> @$path:literal :: $func:ident , $($tail:tt)*) => {
$crate::derive_macro!(($name) -> @$path::$func);
$crate::macros!($($tail)*);
};
(derive($name:ident) -> use $func:ident , $($tail:tt)*) => {
$crate::derive_macro!(($name) -> use $func);
$crate::macros!($($tail)*);
};
(derive($name:ident) -> use $module:ident :: $func:ident , $($tail:tt)*) => {
$crate::derive_macro!(($name) -> use $module::$func);
$crate::macros!($($tail)*);
};
(derive($name:ident) -> mod $func:ident , $($tail:tt)*) => {
$crate::derive_macro!(($name) -> mod $func);
$crate::macros!($($tail)*);
};
(derive($name:ident) -> mod $module:ident :: $func:ident , $($tail:tt)*) => {
$crate::derive_macro!(($name) -> mod $module::$func);
$crate::macros!($($tail)*);
};
(derive($name:ident, attributes($($attr:ident),+)) -> $func:ident , $($tail:tt)*) => {
$crate::derive_macro!(($name, attributes($($attr),+)) -> $func);
$crate::macros!($($tail)*);
};
(derive($name:ident, attributes($($attr:ident),+)) -> @$path:literal :: $func:ident , $($tail:tt)*) => {
$crate::derive_macro!(($name, attributes($($attr),+)) -> @$path::$func);
$crate::macros!($($tail)*);
};
(derive($name:ident, attributes($($attr:ident),+)) -> use $func:ident , $($tail:tt)*) => {
$crate::derive_macro!(($name, attributes($($attr),+)) -> use $func);
$crate::macros!($($tail)*);
};
(derive($name:ident, attributes($($attr:ident),+)) -> mod $func:ident , $($tail:tt)*) => {
$crate::derive_macro!(($name, attributes($($attr),+)) -> mod $func);
$crate::macros!($($tail)*);
};
(function -> $func:ident) => {
$crate::proc_macro!($func -> $func);
};
(function -> $module:ident :: $func:ident) => {
$crate::proc_macro!($func -> $module::$func);
};
(function -> @$path:literal :: $func:ident) => {
$crate::proc_macro!($func -> @$path::$func);
};
(function($name:ident) -> $func:ident) => {
$crate::proc_macro!($name -> $func);
};
(function($name:ident) -> $module:ident :: $func:ident) => {
$crate::proc_macro!($name -> $module::$func);
};
(function($name:ident) -> @$path:literal :: $func:ident) => {
$crate::proc_macro!($name -> @$path::$func);
};
(function($name:ident) -> use $func:ident) => {
$crate::proc_macro!($name -> use $func);
};
(function($name:ident) -> use $module:ident :: $func:ident) => {
$crate::proc_macro!($name -> use $module::$func);
};
(function($name:ident) -> mod $func:ident) => {
$crate::proc_macro!($name -> mod $func);
};
(function($name:ident) -> mod $module:ident :: $func:ident) => {
$crate::proc_macro!($name -> mod $module::$func);
};
(attribute -> $func:ident) => {
$crate::attr_macro!($func -> $func);
};
(attribute -> $module:ident :: $func:ident) => {
$crate::attr_macro!($func -> $module::$func);
};
(attribute -> @$path:literal :: $func:ident) => {
$crate::attr_macro!($func -> @$path::$func);
};
(attribute($name:ident) -> $func:ident) => {
$crate::attr_macro!($name -> $func);
};
(attribute($name:ident) -> $module:ident :: $func:ident) => {
$crate::attr_macro!($name -> $module::$func);
};
(attribute($name:ident) -> @$path:literal :: $func:ident) => {
$crate::attr_macro!($name -> @$path::$func);
};
(attribute($name:ident) -> use $func:ident) => {
$crate::attr_macro!($name -> use $func);
};
(attribute($name:ident) -> use $module:ident :: $func:ident) => {
$crate::attr_macro!($name -> use $module::$func);
};
(attribute($name:ident) -> mod $func:ident) => {
$crate::attr_macro!($name -> mod $func);
};
(attribute($name:ident) -> mod $module:ident :: $func:ident) => {
$crate::attr_macro!($name -> mod $module::$func);
};
(derive($name:ident) -> $func:ident) => {
$crate::derive_macro!(($name) -> $func);
};
(derive($name:ident) -> $module:ident :: $func:ident) => {
$crate::derive_macro!(($name) -> $module::$func);
};
(derive($name:ident) -> @$path:literal :: $func:ident) => {
$crate::derive_macro!(($name) -> @$path::$func);
};
(derive($name:ident, attributes($($attr:ident),+)) -> $func:ident) => {
$crate::derive_macro!(($name, attributes($($attr),+)) -> $func);
};
(derive($name:ident, attributes($($attr:ident),+)) -> $module:ident :: $func:ident) => {
$crate::derive_macro!(($name, attributes($($attr),+)) -> $module::$func);
};
(derive($name:ident, attributes($($attr:ident),+)) -> @$path:literal :: $func:ident) => {
$crate::derive_macro!(($name, attributes($($attr),+)) -> @$path::$func);
};
(derive($name:ident) -> use $func:ident) => {
$crate::derive_macro!(($name) -> use $func);
};
(derive($name:ident) -> use $module:ident :: $func:ident) => {
$crate::derive_macro!(($name) -> use $module::$func);
};
(derive($name:ident, attributes($($attr:ident),+)) -> use $func:ident) => {
$crate::derive_macro!(($name, attributes($($attr),+)) -> use $func);
};
(derive($name:ident, attributes($($attr:ident),+)) -> use $module:ident :: $func:ident) => {
$crate::derive_macro!(($name, attributes($($attr),+)) -> use $module::$func);
};
(derive($name:ident) -> mod $func:ident) => {
$crate::derive_macro!(($name) -> mod $func);
};
(derive($name:ident) -> mod $module:ident :: $func:ident) => {
$crate::derive_macro!(($name) -> mod $module::$func);
};
(derive($name:ident, attributes($($attr:ident),+)) -> mod $func:ident) => {
$crate::derive_macro!(($name, attributes($($attr),+)) -> mod $func);
};
(derive($name:ident, attributes($($attr:ident),+)) -> mod $module:ident :: $func:ident) => {
$crate::derive_macro!(($name, attributes($($attr),+)) -> mod $module::$func);
};
}
#[cfg(test)]
mod tests {
use std::process::Command;
#[test]
fn test_integration_crate() {
let status = Command::new("cargo")
.args(["test", "-p", "integration_test"])
.status()
.expect("Failed to run integration tests");
assert!(status.success(), "Integration tests failed");
}
}