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