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
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
// aslip_macro
use crate::data;
use proc_macro::TokenStream;
use quote::quote;
extern crate proc_macro;
pub fn run_impl(input: TokenStream) -> TokenStream {
let arms: Vec<syn::Arm> = {
let store = data::COMMANDS.lock().expect(concat!(file!(), line!()));
let mut re: Vec<syn::Arm> = vec![];
for (_key, fn_info) in store.iter() {
{
let code = fn_info.gen_case_code();
let a = syn::parse_str::<syn::Arm>(&code).expect(
&("解析 syn::Arm 时出错:".to_string() + concat!(":", file!(), ":", line!())),
);
re.push(a);
}
{
let code = fn_info.gen_short_name_case_code();
if !code.is_empty() {
let a = syn::parse_str::<syn::Arm>(&code).expect(
&("解析 syn::Arm 时出错:".to_string()
+ &code
+ concat!(":", file!(), ":", line!())),
);
re.push(a);
}
}
}
re
};
let app = gen_app_var(input);
// 生成新的代码
let expanded_tokens = quote! {
'block: {
use aslip::types::*;
use aslip::app::App;
#app
match &app._user_inputed_cmd_name {
None => {
app.print_app_help();
}
Some(cmd_name) => {
// app cmd -h
// app cmd --help
if let Some(first_arg) = app._user_inputed_cmd_args.first() {
if first_arg == "-h" || first_arg == "--help" {
app.print_cmd_quick_help_for(cmd_name);
break 'block;
}
};
match cmd_name.as_str() {
"" => panic!("命令的名称不能时 空字符串 \"\"") ,
#(#arms)*
x => {
match x {
"-h" | "--help" | "help" => {
app.print_app_help();
}
"-v" | "--version" | "version" => {
app.print_app_version();
}
v => {
::aslip::tools::color_print::cprintln!("<red,bold>error:</> no such command: <cyan>{:?}</>", v);
}
}
},
};
}
}
};
};
TokenStream::from(expanded_tokens)
}
fn gen_app_var(input: TokenStream) -> proc_macro2::TokenStream {
let lit: syn::Result<syn::Ident> = syn::parse(input.clone());
// let sadf = gen_push_to_app_command_list();
let store = data::COMMANDS.lock().expect(concat!(file!(), line!()));
let mut app_cmds_init: proc_macro2::TokenStream = quote! {};
for (_key, fn_info) in store.iter() {
let code = fn_info.gen_push_to_app_command_list();
app_cmds_init = quote! {
#app_cmds_init
#code
};
}
return match lit {
Ok(variable_ident) => {
// 用户自己定义了一个 aslip::app::App, 则使用用户定义的 aslip::app::App.
quote! {
// let mut app = #variable_ident;
let app: &mut App = &mut #variable_ident;
#app_cmds_init
}
}
Err(_) => {
// 用户没有传入,则使用默认实现。
quote! {
let mut app = ::aslip::app::App::new();
#app_cmds_init
}
}
};
}