1mod macro_args;
2
3use crate::macro_args::MacroArgs;
4use darling::FromMeta;
5use proc_macro::TokenStream;
6use quote::quote;
7use syn::{AttributeArgs, ItemFn};
8
9#[proc_macro_attribute]
27pub fn proc_lock(args: TokenStream, input: TokenStream) -> TokenStream {
28 let options = syn::parse_macro_input!(args as AttributeArgs);
29 let function = syn::parse_macro_input!(input as ItemFn);
30
31 let MacroArgs { name, absolute } = match MacroArgs::from_list(&options) {
32 Ok(v) => v,
33 Err(e) => return TokenStream::from(e.write_errors()),
34 };
35
36 let locking_code = quote! {
37 use proc_lock::{lock, try_lock, LockPath};
38 let lock_path = if #absolute {
39 LockPath::FullPath(#name)
40 } else {
41 LockPath::Tmp(#name)
42 };
43
44 let _guard = lock(&lock_path).unwrap();
45 };
46
47 let ItemFn {
48 attrs,
49 vis,
50 sig,
51 block: body,
52 } = &function;
53
54 let result = quote! {
55 #(#attrs)*
56 #vis #sig {
57 #locking_code
58 #body
59 }
60 };
61
62 let res: proc_macro::TokenStream = result.into();
63 res
64}