redis_lua_macro/
lib.rs

1extern crate proc_macro;
2
3use self::proc_macro::{TokenStream as TokenStream1, TokenTree};
4use proc_macro2::TokenStream;
5use proc_macro_error::proc_macro_error;
6use quote::quote;
7
8mod chains;
9mod check;
10mod file;
11mod patterns;
12mod script;
13mod token;
14
15use crate::{
16    chains::ChainIter,
17    check::Checker,
18    patterns::{all, caps},
19    script::Script,
20};
21
22use proc_macro_hack::proc_macro_hack;
23
24fn to_ident(tt: &TokenTree) -> TokenStream {
25    let s: TokenStream1 = tt.clone().into();
26    s.into()
27}
28
29fn gen_all(script: &Script) -> TokenStream {
30    let mut s = TokenStream::new();
31
32    let chains = ChainIter::new(script);
33    let pchains = chains.pchains();
34
35    for c in chains {
36        s.extend(c.gen());
37    }
38
39    for c in pchains {
40        s.extend(c.gen());
41    }
42
43    s
44}
45
46#[proc_macro_error]
47#[proc_macro_hack]
48pub fn lua(input: TokenStream1) -> TokenStream1 {
49    let script = Script::new(input, true);
50
51    Checker::new()
52        .defines(all(&script).map(|(_, arg)| arg.as_lua().into()).collect())
53        .check(&script);
54
55    let defs = gen_all(&script);
56
57    let body_str = script.script();
58    let script_str = script.wrap();
59
60    let args = all(&script).map(|(_, arg)| {
61        let arg = arg.as_lua().to_string();
62        quote! { #arg }
63    });
64
65    let caps = caps(&script).map(|(_, arg)| {
66        let arg = to_ident(arg.as_rust());
67        quote! { #arg }
68    });
69
70    let script_code = quote! {
71        {
72            use redis_lua::Script;
73
74            #defs
75
76            Chain0::new(redis_lua::Info::new(#script_str, #body_str, &[#(#args),*]), (), #(#caps),*)
77        }
78    };
79    script_code.into()
80}
81
82#[proc_macro_error]
83#[proc_macro_hack]
84pub fn lua_s(input: TokenStream1) -> TokenStream1 {
85    let script = Script::new(input, false);
86
87    Checker::new().define("ARGV").check(&script);
88
89    let script = script.script();
90    let script_code = quote! {
91        #script
92    };
93    script_code.into()
94}