sqlite_loadable_macros/
lib.rs1use proc_macro2::Ident;
2
3use syn::{parse_macro_input, spanned::Spanned, Item};
4
5use proc_macro::TokenStream;
6use quote::quote_spanned;
7
8#[proc_macro_attribute]
10pub fn sqlite_entrypoint(_attr: TokenStream, item: TokenStream) -> TokenStream {
11 let ast = parse_macro_input!(item as syn::Item);
12 match ast {
13 Item::Fn(mut func) => {
14 let c_entrypoint = func.sig.ident.clone();
15
16 let original_funcname = func.sig.ident.to_string();
17 func.sig.ident = Ident::new(
18 format!("_{}", original_funcname).as_str(),
19 func.sig.ident.span(),
20 );
21
22 let prefixed_original_function = func.sig.ident.clone();
23
24 quote_spanned! {func.span()=>
25 #func
26
27 #[no_mangle]
32 pub unsafe extern "C" fn #c_entrypoint(
33 db: *mut sqlite3,
34 pz_err_msg: *mut *mut c_char,
35 p_api: *mut sqlite3_api_routines,
36 ) -> c_uint {
37 register_entrypoint(db, pz_err_msg, p_api, #prefixed_original_function)
38 }
39
40
41 }
42 .into()
43 }
44 _ => panic!("Only function items are allowed on sqlite_entrypoint"),
45 }
46}
47
48#[proc_macro_attribute]
50pub fn sqlite_entrypoint_permanent(_attr: TokenStream, item: TokenStream) -> TokenStream {
51 let ast = parse_macro_input!(item as syn::Item);
52 match ast {
53 Item::Fn(mut func) => {
54 let c_entrypoint = func.sig.ident.clone();
55
56 let original_funcname = func.sig.ident.to_string();
57 func.sig.ident = Ident::new(
58 format!("_{}", original_funcname).as_str(),
59 func.sig.ident.span(),
60 );
61
62 let prefixed_original_function = func.sig.ident.clone();
63
64 quote_spanned! {func.span()=>
65 #func
66
67 #[no_mangle]
72 pub unsafe extern "C" fn #c_entrypoint(
73 db: *mut sqlite3,
74 pz_err_msg: *mut *mut c_char,
75 p_api: *mut sqlite3_api_routines,
76 ) -> c_uint {
77 register_entrypoint_load_permanently(db, pz_err_msg, p_api, #prefixed_original_function)
78 }
79
80
81 }
82 .into()
83 }
84 _ => panic!("Only function items are allowed on sqlite_entrypoint"),
85 }
86}