grafbase_sdk_derive/
lib.rs

1use proc_macro::TokenStream;
2use quote::quote;
3use syn::DeriveInput;
4
5/// A proc macro for generating initialization code for a resolver extension.
6///
7/// Add it on top of the type which implements `Extension` and `Resolver` traits to
8/// register it as a resolver extension.
9#[proc_macro_derive(ResolverExtension)]
10pub fn resolver_extension(input: TokenStream) -> TokenStream {
11    let ast = syn::parse_macro_input!(input as DeriveInput);
12    expand(resolver_init(ast))
13}
14
15/// A proc macro for generating initialization code for an authentication extension.
16///
17/// Add it on top of the type which implements `Extension` and `Authenticator` traits to
18/// register it as a resolver extension.
19#[proc_macro_derive(AuthenticationExtension)]
20pub fn authentication_extension(input: TokenStream) -> TokenStream {
21    let ast = syn::parse_macro_input!(input as DeriveInput);
22    expand(authentication_init(ast))
23}
24
25fn expand(init: proc_macro2::TokenStream) -> TokenStream {
26    let token_stream = quote! {
27        #[doc(hidden)]
28        #[unsafe(export_name = "register-extension")]
29        pub extern "C" fn __register_extension() {
30            #init
31        }
32    };
33
34    TokenStream::from(token_stream)
35}
36
37fn resolver_init(ast: DeriveInput) -> proc_macro2::TokenStream {
38    let name = &ast.ident;
39
40    let (_, ty_generics, _) = ast.generics.split_for_impl();
41
42    quote! {
43        grafbase_sdk::extension::resolver::register::<#name #ty_generics>();
44    }
45}
46
47fn authentication_init(ast: DeriveInput) -> proc_macro2::TokenStream {
48    let name = &ast.ident;
49
50    let (_, ty_generics, _) = ast.generics.split_for_impl();
51
52    quote! {
53        grafbase_sdk::extension::authentication::register::<#name #ty_generics>();
54    }
55}