1use darling::FromDeriveInput;
2use quote::quote;
3use syn::{parse_macro_input, DeriveInput, Ident, Type};
4
5#[derive(Debug, FromDeriveInput)]
6#[darling(attributes(context))]
7struct ContextDeriveInput {
8 ident: Ident,
9 state: Type,
10}
11
12#[proc_macro_derive(Context, attributes(context))]
18pub fn derive_context(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
19 let input = parse_macro_input!(input as DeriveInput);
20
21 let ContextDeriveInput { ident, state } = match ContextDeriveInput::from_derive_input(&input) {
22 Ok(input) => input,
23 Err(err) => return err.write_errors().into(),
24 };
25
26 let expanded = quote! {
27 impl qcontext::Context for #ident {
28 type State = #state;
29
30 fn context() -> &'static qcontext::OnceCell<Self::State> {
31 static CONTEXT: qcontext::OnceCell<#state> = qcontext::OnceCell::new();
32
33 &CONTEXT
34 }
35 }
36 };
37
38 expanded.into()
39}