1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
use proc_macro2::TokenStream;
use quote::quote;
use syn::spanned::Spanned;
use super::*;
pub fn build(args: RunCliArgs) -> TokenStream {
let mut command_handler = args.command.clone();
let mut arguments = std::mem::replace(
&mut command_handler.segments.last_mut().unwrap().arguments,
PathArguments::None,
);
let command = command_handler.clone();
if let PathArguments::AngleBracketed(a) = &mut arguments {
a.args.push(syn::parse2(quote! { () }).unwrap());
a.args.push(syn::parse2(quote! { _ }).unwrap());
}
command_handler.segments.push(PathSegment {
ident: Ident::new("cli_handler", command.span()),
arguments,
});
let app = if let Some(mut_app) = args.mut_app {
let ident = mut_app.app_ident;
let body = mut_app.body;
quote! {
{
let #ident = #command::build_app();
#body
}
}
} else {
quote! { #command::build_app() }
};
let make_ctx = if let Some(make_ctx) = args.make_ctx {
let ident = make_ctx.matches_ident;
let body = make_ctx.body;
quote! {
{
let #ident = &rpc_toolkit_matches;
#body
}
}
} else {
quote! { &rpc_toolkit_matches }
};
let parent_data = if let Some(data) = args.parent_data {
quote! { #data }
} else {
quote! { () }
};
let exit_fn = args.exit_fn.unwrap_or_else(|| {
syn::parse2(quote! { |err: ::rpc_toolkit::yajrc::RpcError| {
eprintln!("{}", err.message);
if let Some(data) = err.data {
eprintln!("{}", data);
}
std::process::exit(err.code);
} })
.unwrap()
});
quote! {
{
let rpc_toolkit_matches = #app.get_matches();
let rpc_toolkit_ctx = #make_ctx;
let rpc_toolkit_parent_data = #parent_data;
if let Err(err) = #command_handler(
rpc_toolkit_ctx,
rpc_toolkit_parent_data,
None,
&rpc_toolkit_matches,
"".into(),
(),
) {
drop(rpc_toolkit_matches);
(#exit_fn)(err);
} else {
drop(rpc_toolkit_matches);
}
}
}
}