1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47
use drone_macros_core::parse_ident; use proc_macro::TokenStream; use quote::{format_ident, quote}; use syn::{ parenthesized, parse::{Parse, ParseStream, Result}, parse_macro_input, punctuated::Punctuated, LitStr, Token, }; #[allow(dead_code)] enum Input { Lit { string: LitStr }, Concat { strings: Vec<LitStr> }, } impl Parse for Input { fn parse(input: ParseStream<'_>) -> Result<Self> { if input.peek(LitStr) { let string = input.parse()?; Ok(Self::Lit { string }) } else { parse_ident!(input, "concat"); input.parse::<Token![!]>()?; let content; parenthesized!(content in input); let strings = content.call(Punctuated::<_, Token![,]>::parse_terminated)?.into_iter().collect(); Ok(Self::Concat { strings }) } } } pub fn proc_macro(input: TokenStream) -> TokenStream { let input = &parse_macro_input!(input); let name = match input { Input::Lit { string } => string.value(), Input::Concat { strings } => strings.iter().map(LitStr::value).collect::<Vec<_>>().concat(), }; let ident = format_ident!("__assert_register_block_taken_{}", name); let expanded = quote! { #[no_mangle] fn #ident() {} }; expanded.into() }