1use proc_macro::TokenStream;
2use quote::quote;
3use syn::{DeriveInput, parse_macro_input};
4
5#[proc_macro_derive(Payload, attributes(payload))]
33pub fn derive_payload(input: TokenStream) -> TokenStream {
34 let input = parse_macro_input!(input as DeriveInput);
35 let name = &input.ident;
36 let (impl_generics, ty_generics, where_clause) = input.generics.split_for_impl();
37
38 let mut storage = String::from("serde");
40 for attr in &input.attrs {
41 if attr.path().is_ident("payload") {
42 let _ = attr.parse_nested_meta(|meta| {
43 if meta.path.is_ident("storage") {
44 let value = meta.value()?;
45 let s: syn::LitStr = value.parse()?;
46 storage = s.value();
47 }
48 Ok(())
49 });
50 }
51 }
52
53 let expanded = match storage.as_str() {
54 "pod" => quote! {
55 impl #impl_generics ::ringdb::Payload for #name #ty_generics #where_clause {
56 type Store = ::ringdb::__private::PodStore<Self>;
57 type Builder = ::ringdb::__private::PodStoreBuilder<Self>;
58
59 fn make_builder() -> ::ringdb::__private::Result<Self::Builder> {
60 ::ringdb::__private::PodStoreBuilder::new()
61 }
62
63 fn load_store(dir: &::std::path::Path) -> ::ringdb::__private::Result<Self::Store> {
64 ::ringdb::__private::PodStore::load(&dir.join("payloads.bin"))
65 }
66 }
67 },
68 _ => quote! {
69 impl #impl_generics ::ringdb::Payload for #name #ty_generics #where_clause {
70 type Store = ::ringdb::__private::SerdeStore<Self>;
71 type Builder = ::ringdb::__private::SerdeStoreBuilder<Self>;
72
73 fn make_builder() -> ::ringdb::__private::Result<Self::Builder> {
74 ::ringdb::__private::SerdeStoreBuilder::new()
75 }
76
77 fn load_store(dir: &::std::path::Path) -> ::ringdb::__private::Result<Self::Store> {
78 ::ringdb::__private::SerdeStore::load(
79 &dir.join("payloads.bin"),
80 &dir.join("offsets.bin"),
81 )
82 }
83 }
84 },
85 };
86
87 TokenStream::from(expanded)
88}