Skip to content

Instantly share code, notes, and snippets.

@thomcc
Last active February 6, 2020 10:43
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save thomcc/bc2b89e05f52c3392178be0e3e0db7c6 to your computer and use it in GitHub Desktop.
Save thomcc/bc2b89e05f52c3392178be0e3e0db7c6 to your computer and use it in GitHub Desktop.
proc-macros for wrapping things with normal macros
extern crate proc_macro;
use proc_macro::{Delimiter, Group, TokenStream, TokenTree};
/// usage:
/// ```
/// #[wrap_with(my_macro!)]
/// pub struct Blah { ... }
/// ```
///
/// becomes
///
/// ```
/// my_macro! {
/// pub struct Blah { ... }
/// }
/// ```
#[proc_macro_attribute]
pub fn wrap_with(mut attrs: TokenStream, input: TokenStream) -> TokenStream {
if let Some(TokenTree::Punct(ref punct)) = attrs.clone().into_iter().last() {
assert_eq!(punct.as_char(), '!', "Syntax: #[wrap_with(my_macro!)]");
}
let wrapper = TokenTree::Group(Group::new(Delimiter::Brace, input.into_iter().collect()));
attrs.extend(std::iter::once(wrapper));
attrs
}
/// usage:
/// ```
/// #[derive_with(my_macro!)]
/// pub struct Blah { ... }
/// ```
///
/// becomes
///
/// ```
/// pub struct Blah { ... }
/// my_macro! {
/// pub struct Blah { ... }
/// }
/// ```
/// same as `wrap_with` but always outputs the struct definition in addition to
/// whatever my_macro generates.
#[proc_macro_attribute]
pub fn derive_with(attrs: TokenStream, input: TokenStream) -> TokenStream {
let mut ret = input.clone();
ret.extend(wrap_with(attrs, input));
ret
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment