1#![doc = include_str!("../README.md")]
2
3use proc_macro::TokenStream;
4use proc_macro2::Ident;
5use quote::{quote, format_ident};
6use syn::{Generics, ItemFn, ItemStatic, Signature, Token, parse_macro_input, spanned::Spanned};
7
8#[proc_macro_attribute]
9#[doc = include_str!("../README.md")]
10pub fn null_fn(_: TokenStream, input: TokenStream) -> TokenStream {
11 let mut static_item = parse_macro_input!(input as ItemStatic);
12
13 let null_fn = ItemFn {
14 attrs: vec![],
15 vis: syn::parse_str("pub(super)").unwrap(),
16 block: syn::parse_str("{ panic!(\"This function has not been initialized yet\") }").unwrap(),
17 sig: Signature {
18 constness: None,
19 asyncness: None,
20 unsafety: Some(Token)),
21 abi: None,
22 fn_token: Default::default(),
23 ident: Ident::new("null_fn", static_item.span()),
24 generics: Generics::default(),
25 paren_token: Default::default(),
26 inputs: Default::default(),
27 variadic: Default::default(),
28 output: syn::ReturnType::Default
29 },
30 };
31
32 static_item.expr = syn::parse_str(&format!("unsafe{{std::mem::transmute(__null_fn__{}::null_fn as *const ())}}", static_item.ident)).unwrap();
33
34 let mod_name = format_ident!("__null_fn__{}", static_item.ident);
35 quote!(
36 #[allow(non_snake_case)]
37 mod #mod_name {
38 #[allow(unused_variables)]
39 #null_fn
40 }
41 #static_item
42 ).into()
43}