1#![allow(dead_code)]
2
3use proc_quote::quote;
4
5#[proc_macro_derive(DbName, attributes(name, flags, table))]
6pub fn derive_db_name(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
7 let input = syn::parse_macro_input!(input as syn::DeriveInput);
8 let name = &input.ident;
9
10 let mut db_name = None;
11 let mut flags = None;
12 let mut table = None;
13 for attr in input.attrs {
14 let args = attr.meta.require_list().unwrap();
15 match &attr.path().get_ident().unwrap().to_string() as &str {
16 "name" => {
17 let lit = args.parse_args::<syn::LitStr>().unwrap();
18 db_name = Some(syn::LitByteStr::new(format!("{}\0", lit.value()).as_bytes(), lit.span()));
19 },
20 "flags" => { flags = Some(args.parse_args::<syn::Expr>().unwrap()); },
21 "table" => { table = Some(args.parse_args::<syn::Type>().unwrap()); },
22 _ => unreachable!(),
23 }
24 }
25
26 let flags = flags.map_or_else(|| quote!(), |x| quote!(fn flags() -> ::batadase::enumflags2::BitFlags<::batadase::lmdb::DbFlags> { #x.into() }));
27 let db_name = db_name.map_or_else(|| quote!(&::std::concat!(::std::module_path!(), "::", ::std::stringify!(#name), "\0").as_bytes()), |x| quote!(#x));quote!(
30 impl ::batadase::DbName for #name {
31 type Table<'tx, TX: ::batadase::transaction::Transaction> = #table;
32 const NAME: &'static [u8] = #db_name;
33
34 fn get<TX: ::batadase::transaction::Transaction>(tx: &TX) -> Self::Table<'_, TX> { Self::Table::build(tx, crate::db::ENV.db(Self::NAME).unwrap()) }
35 #flags
36 }
37 ).into()
38}