Macro core_extensions::split_generics_and_where [−][src]
macro_rules! split_generics_and_where { ( $(:: $(@$leading:tt@)? )? $first:ident $(:: $trailing:ident)* ! $prefix:tt ($($generics:tt)*) ) => { ... }; }
This is supported on crate feature
generics_parsing only.For parsing item definitions, passing the generic parameters unchanged to a callback macro.
Version compatibility
This macro can only be used inside of functions since Rust 1.45.0, before that version it can only be used outside of functions.
Examples
Basic
Basic example 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::split_generics_and_where; fn main() { assert_eq!(hello(), "world") } // `split_generics_and_where` calls `crate::foo` here split_generics_and_where! { crate::foo!{ // The first tokens passed to the `crate::foo` macro hello "world" foo bar } ( // The parsed tokens <'a, T: Foo, const N: usize> (param: Type) -> u32 where T: Bar, { println } ) } #[macro_export] macro_rules! foo { ( $fn_name:ident $string:literal foo bar ('a, T: Foo, const N: usize) // the generic parameters ((param: Type) -> u32 ) // before the where clause (T: Bar,) // inside the where clause ( { println } ) // after the where clause ) => { fn $fn_name() -> &'static str { $string } }; }
Parsing a function
This demonstrates how you can parse a function.
use core_extensions::split_generics_and_where; use std::ops::Mul; crate::inject_increment! { pub fn square(x: u32) -> u32 { x * x } } crate::inject_increment! { pub(crate) unsafe fn cube<T>(x: T) -> T where T: Mul<Output = T> + Copy { x * x * x } } fn main() { assert_eq!(get_count(), 0); assert_eq!(square(3), 9); assert_eq!(get_count(), 1); assert_eq!(unsafe{ cube(5) }, 125); assert_eq!(get_count(), 2); } #[macro_export] macro_rules! inject_increment { ( $(#[$attr:meta])* $vis:vis $(unsafe $(@$unsafe:tt@)?)? fn $name:ident $($rem:tt)* ) => { split_generics_and_where!{ $crate::__priv_inject_increment! { $(#[$attr])* $vis, ($(unsafe $(@$unsafe@)?)?) fn $name } ($($rem)*) } } } #[doc(hidden)] #[macro_export] macro_rules! __priv_inject_increment{ ( $(#[$attr:meta])* $vis:vis, ($($unsafe:tt)?) fn $name:ident ( $($generics:tt)* ) ( ($($fn_params:tt)*) $( -> $ret_ty:ty )? ) ( $($where_preds:tt)* ) ( { $($code:tt)* } ) ) => { $(#[$attr])* $vis $($unsafe)? fn $name< $($generics)* > ( $($fn_params)* ) $( -> $ret_ty )? where $($where_preds)* { $crate::increment_count(); $($code)* } } } use std::sync::atomic::{AtomicU64, Ordering as AtomOrd}; pub static COUNT: AtomicU64 = AtomicU64::new(0); fn increment_count() { COUNT.fetch_add(1, AtomOrd::Relaxed); } fn get_count() -> u64 { COUNT.load(AtomOrd::Relaxed) }