1extern crate proc_macro;
2
3use proc_macro::{TokenStream};
4use quote::quote;
5use syn::{parse_macro_input, ItemFn, LitStr, Expr};
6
7#[proc_macro_attribute]
8pub fn activate_log(args: TokenStream, input: TokenStream) -> TokenStream {
9 let log_file = parse_macro_input!(args as LitStr);
10 let input_fn = parse_macro_input!(input as ItemFn);
11
12 let output = quote! {
13 #input_fn
14
15 fn initialize_logger() {
16 crypt_guard::initialize_logger(std::path::PathBuf::from(#log_file));
17 }
18 };
19
20 TokenStream::from(output)
21}
22
23#[proc_macro]
24pub fn concat_cipher(input: TokenStream) -> TokenStream {
25 let inputs = parse_macro_input!(input as Expr);
26
27 let output = quote! {
28 {
29 let key = hex::encode(#inputs.0);
30 let cipher = hex::encode(#inputs.1);
31 format!("{}${}", key, cipher)
32 }
33 };
34
35 TokenStream::from(output)
36}
37
38#[proc_macro]
39pub fn split_cipher(input: TokenStream) -> TokenStream {
40 let expr = parse_macro_input!(input as Expr);
41
42 let output = quote! {
43 {
44 let parts: Vec<&str> = #expr.split('$').collect();
45 if parts.len() != 2 {
46 Err(hex::FromHexError::OddLength)
47 } else {
48 match (hex::decode(parts[0]), hex::decode(parts[1])) {
49 (Ok(key), Ok(cipher)) => Ok((key, cipher)),
50 (Err(e), _) | (_, Err(e)) => Err(e),
51 }
52 }
53 }
54 };
55
56 TokenStream::from(output)
57}
58
59struct LogActivityInput {
60 process: Expr,
61 detail: Expr,
62}
63
64impl syn::parse::Parse for LogActivityInput {
65 fn parse(input: syn::parse::ParseStream) -> syn::Result<Self> {
66 let process: Expr = input.parse()?;
67 input.parse::<syn::Token![,]>()?;
68 let detail: Expr = input.parse()?;
69
70 Ok(LogActivityInput { process, detail })
71 }
72}
73
74#[proc_macro]
75pub fn log_activity(input: TokenStream) -> TokenStream {
76 let LogActivityInput { process, detail } = parse_macro_input!(input as LogActivityInput);
77
78 let output = quote! {
79 match LOGGER.lock() {
80 Ok(mut logger) => {
81 let _ = logger.append_log(&format!("{}", #process), &format!("{}", #detail));
82 },
83 Err(e) => eprintln!("Logger lock error: {}", e),
84 }
85 };
86
87 TokenStream::from(output)
88}
89
90#[proc_macro]
91pub fn write_log(_input: TokenStream) -> TokenStream {
92 let output = quote! {
93 {
94 let mut logger = LOGGER.lock().expect("Logger lock failed");
95 if let Err(e) = logger.write_log_file() {
96 eprintln!("Failed to write log file: {:?}", e);
97 }
98 logger.log.clear();
99 }
100 };
101
102 TokenStream::from(output)
103}