log_attributes/
lib.rs

1extern crate proc_macro;
2
3use proc_macro::TokenStream;
4
5use config::Config;
6use fn_processor::FnProcessor;
7
8mod fn_processor;
9mod fmt_args;
10mod config;
11
12#[test]
13fn tests() {
14    let t = trybuild::TestCases::new();
15    t.pass("tests/pass/*.rs");
16    t.compile_fail("tests/fail/*.rs");
17}
18
19fn log_with_config(input: syn::ItemFn, config: Result<Config, syn::Error>) -> TokenStream {
20    let res = config
21        .map(|config| FnProcessor::new(input, config))
22        .and_then(FnProcessor::parse_fmt_args)
23        .map(FnProcessor::insert_log_statements)
24        .map(FnProcessor::into_tokens);
25
26    match res {
27        Ok(ts) => ts.into(),
28        Err(err) => err.to_compile_error().into(),
29    }
30}
31
32fn log_with_level(args: TokenStream, input: TokenStream, log_level: log::Level) -> TokenStream {
33    let args = syn::parse_macro_input!(args as syn::AttributeArgs);
34    let input = syn::parse_macro_input!(input as syn::ItemFn);
35
36    log_with_config(
37        input,
38        Config::with_log_level(args.into_iter(), log_level),
39    )
40}
41
42#[proc_macro_attribute]
43pub fn log(args: TokenStream, input: TokenStream) -> TokenStream {
44    let args = syn::parse_macro_input!(args as syn::AttributeArgs);
45    let input = syn::parse_macro_input!(input as syn::ItemFn);
46
47    log_with_config(
48        input,
49        Config::new(args.into_iter()),
50    )
51}
52
53#[proc_macro_attribute]
54pub fn trace(args: TokenStream, input: TokenStream) -> TokenStream {
55    log_with_level(args, input, log::Level::Trace)
56}
57
58#[proc_macro_attribute]
59pub fn debug(args: TokenStream, input: TokenStream) -> TokenStream {
60    log_with_level(args, input, log::Level::Debug)
61}
62
63#[proc_macro_attribute]
64pub fn info(args: TokenStream, input: TokenStream) -> TokenStream {
65    log_with_level(args, input, log::Level::Info)
66}
67
68#[proc_macro_attribute]
69pub fn warn(args: TokenStream, input: TokenStream) -> TokenStream {
70    log_with_level(args, input, log::Level::Warn)
71}
72
73#[proc_macro_attribute]
74pub fn error(args: TokenStream, input: TokenStream) -> TokenStream {
75    log_with_level(args, input, log::Level::Error)
76}