component_init_macro/
lib.rs1use proc_macro::TokenStream;
2use quote::{quote, quote_spanned};
3use syn::{ItemFn, parse_macro_input, spanned::Spanned};
4
5#[proc_macro_attribute]
6pub fn init(_attr: TokenStream, item: TokenStream) -> TokenStream {
7 let input = parse_macro_input!(item as ItemFn);
8 if input.sig.asyncness.is_some() {
9 return quote_spanned! { input.sig.fn_token.span()=>
10 compile_error!("fn cannot be async");
11 }
12 .into();
13 }
14 if !input.sig.inputs.is_empty() {
15 return quote_spanned! { input.sig.inputs.span()=>
16 compile_error!("function cannot have arguments");
17 }
18 .into();
19 }
20 let callee = &input.sig.ident;
21
22 quote! {
23 #input
24
25 mod __component_init {
26 component_init::__bindgen::generate!({
27 inline: r"
28 package this:wit;
29 world w {
30 export component-init: func();
31 }
32 ",
33 runtime_path: "component_init::__bindgen::rt",
34 });
35 struct __S;
36 impl Guest for __S {
37 fn component_init() {
38 super::#callee()
39 }
40 }
41 export!(__S);
42 }
43 }
44 .into()
45}