commander_macros/
tools.rs

1use syn::punctuated::Punctuated;
2use syn::{ FnArg, Ident };
3use syn::token;
4use quote::quote;
5use proc_macro2::{ TokenStream as TokenStream2 };
6
7/// Generate inputs of command processing function.
8///
9/// Why need it? Because the length of inputs is unknown, maybe 1 maybe 10.
10/// But we need a common way to call it, so we need to generate inputs tokens needed.
11
12#[doc(hidden)]
13pub fn generate_call_fn(inputs: &Punctuated<FnArg, token::Comma>, call_fn_name: &Ident, fn_name: &Ident) -> TokenStream2 {
14    let mut tokens: Vec<TokenStream2> = vec![];
15
16    for (idx, arg) in inputs.iter().enumerate() {
17        if let FnArg::Captured(cap) = arg {
18            let ty = &cap.ty;
19
20            if idx < inputs.len() - 1 {
21                tokens.push((quote! {
22                    {
23                        <#ty>::from(raws[#idx].clone())
24                    }
25                }).into());
26            } else {
27                let ts = TokenStream2::from(quote! {
28                    #ty
29                });
30                let mut ts_str = ts.to_string();
31
32                ts_str.retain(|c| !char::is_whitespace(c));
33
34                if ts_str != "Cli" {
35                    tokens.push((quote! {
36                        {
37                            <#ty>::from(raws[#idx].clone())
38                        }
39                    }).into());
40                } else {
41                    tokens.push((quote! {
42                        {
43                            cli
44                        }
45                    }).into());
46                }
47            }
48        }
49    }
50
51    (quote! {
52        fn #call_fn_name(raws: &Vec<_commander_rust_Raw>, cli: _commander_rust_Cli) {
53            #fn_name(#(#tokens,)*)
54        }
55    }).into()
56}