batadase_macros/
lib.rs

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));//syn::LitByteStr::new(format!("{}\0", name).as_bytes(), name.span()));
28
29	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}