Macro core_extensions::impl_split
source · [−]macro_rules! impl_split {
($($args:tt)*) => { ... };
}
Available on crate feature
item_parsing
only.Expand description
For parsing impl blocks, passing the generic parameters unchanged to a callback macro.
Example
Basic
Basic examples of using this macro, and what it passes to a callback macro.
For a more realistic example you can look at the one below
use core_extensions::impl_split;
assert_eq!(hello(), "world");
// impl_split invokes `bar` here
impl_split!{
crate::bar!{
// The first tokens passed to the `bar` macro
hello "world" foo bar
}
(
#[foo]
unsafe impl<T: Foo> Trait<X, Y> for Type
where U: Bar
{
fn hello(){}
}
)
}
#[macro_export]
macro_rules! bar {
(
$fn_name:ident $returns:literal foo bar
// the attributes
(#[foo])
// the qualifiers (if `const impl` becomes a thing, i'll be included here)
(unsafe)
// the generic parameters
(T: Foo)
// the imlpemented trait.
// If this not a trait impl, then `trait(....)` is not passed
trait(Trait<X, Y>)
// the type that this is an impl for
type(Type)
// inside the where clause, this always has a trailing comma
(U: Bar,)
// the body of the impl
({ fn hello() {} })
) => {
fn $fn_name() -> &'static str {
$returns
}
}
}
More Realistic Example
This only works in Rust 1.45.0 onwards.
pub use core_extensions::{impl_split, rewrap_macro_parameters};
struct Wrapper<T>(T, [u32; 3]);
crate::constify_methods!{
impl<T> Wrapper<T> {
pub fn get(&self) -> &T {
&self.0
}
pub fn sum(&self) -> u32 {
let [a, b, c] = self.1;
a + b + c
}
}
}
const SUM: u32 = Wrapper((), [3, 5, 8]).sum();
fn main() {
assert_eq!(SUM, 16);
}
#[macro_export]
macro_rules! constify_methods {
($impl:item) => {
$crate::impl_split!{
$crate::__priv_constify_methods!{@parse_impl}
($impl)
}
}
}
#[doc(hidden)]
#[macro_export]
macro_rules! __priv_constify_methods{
(
@parse_impl
($(#[$impl_attr:meta])*)
($($qualifiers:tt)*) // Can be `unsafe` (maybe `const` in the future)
($($generics:tt)*)
$( trait($($trait:tt)*) )?
type ($($type:tt)*)
($($where:tt)*)
({ $($item:item)* })
) => {
$(#[$impl_attr])*
$($qualifiers)* impl<$($generics)*> $($($trait)* for )? $($type)*
where
$($where)*
{
$crate::rewrap_macro_parameters!{$(
$crate::__priv_constify_methods!{
@method
$item
~$item
}
)*}
}
};
(
@method $item:item (
$(#[$attr:meta])*
$vis:vis
$(unsafe $(@$unsafe:tt@)?)?
fn
$($rem:tt)*
)
) => {
$(#[$attr])*
$vis const $(unsafe $(@$unsafe@)?)? fn
$($rem)*
};
(@method $item:item $paren:tt) => {
$item
};
}