@@ -5,6 +5,8 @@ use syn::{self, spanned::Spanned};
5
5
pub ( crate ) struct Args {
6
6
pub ( crate ) prefix_enter : String ,
7
7
pub ( crate ) prefix_exit : String ,
8
+ pub ( crate ) format_enter : Option < String > ,
9
+ pub ( crate ) format_exit : Option < String > ,
8
10
pub ( crate ) filter : Filter ,
9
11
pub ( crate ) pause : bool ,
10
12
pub ( crate ) pretty : bool ,
@@ -23,6 +25,17 @@ const DEFAULT_PAUSE: bool = false;
23
25
const DEFAULT_PRETTY : bool = false ;
24
26
const DEFAULT_LOGGING : bool = false ;
25
27
28
+ macro_rules! try_extract_str {
29
+ ( $lit: expr, $meta: expr, $arg_ty: ident) => { {
30
+ match * $lit {
31
+ syn:: Lit :: Str ( ref lit_str) => Ok ( Arg :: $arg_ty( $meta. span( ) , lit_str. value( ) ) ) ,
32
+ _ => Err ( vec![ syn:: Error :: new_spanned(
33
+ $lit,
34
+ format!( "`{}` must have a string value" , stringify!( $arg_ty) ) ,
35
+ ) ] ) ,
36
+ }
37
+ } } ;
38
+ }
26
39
impl Args {
27
40
pub ( crate ) fn from_raw_args ( raw_args : syn:: AttributeArgs ) -> Result < Self , Vec < syn:: Error > > {
28
41
// Different types of arguments accepted by `#[trace]`;
@@ -35,6 +48,8 @@ impl Args {
35
48
Pause ( proc_macro2:: Span , bool ) ,
36
49
Pretty ( proc_macro2:: Span , bool ) ,
37
50
Logging ( proc_macro2:: Span , bool ) ,
51
+ FormatEnter ( proc_macro2:: Span , String ) ,
52
+ FormatExit ( proc_macro2:: Span , String ) ,
38
53
}
39
54
40
55
// Parse arguments
@@ -43,6 +58,8 @@ impl Args {
43
58
enum ArgName {
44
59
PrefixEnter ,
45
60
PrefixExit ,
61
+ FormatEnter ,
62
+ FormatExit ,
46
63
Enable ,
47
64
Disable ,
48
65
Pause ,
@@ -54,6 +71,8 @@ impl Args {
54
71
let arg_name = match ident. to_string ( ) . as_str ( ) {
55
72
"prefix_enter" => ArgName :: PrefixEnter ,
56
73
"prefix_exit" => ArgName :: PrefixExit ,
74
+ "format_enter" => ArgName :: FormatEnter ,
75
+ "format_exit" => ArgName :: FormatExit ,
57
76
"enable" => ArgName :: Enable ,
58
77
"disable" => ArgName :: Disable ,
59
78
"pause" => ArgName :: Pause ,
@@ -79,6 +98,18 @@ impl Args {
79
98
"`prefix_exit` requires a string value" ,
80
99
) ]
81
100
} ;
101
+ let format_enter_type_error = || {
102
+ vec ! [ syn:: Error :: new_spanned(
103
+ ident. clone( ) ,
104
+ "`format_enter` requires a string value" ,
105
+ ) ]
106
+ } ;
107
+ let format_exit_type_error = || {
108
+ vec ! [ syn:: Error :: new_spanned(
109
+ ident. clone( ) ,
110
+ "`format_exit` requires a string value" ,
111
+ ) ]
112
+ } ;
82
113
let enable_type_error = || {
83
114
vec ! [ syn:: Error :: new_spanned(
84
115
ident. clone( ) ,
@@ -115,11 +146,12 @@ impl Args {
115
146
ArgName :: Pause => Ok ( Arg :: Pause ( meta. span ( ) , true ) ) ,
116
147
ArgName :: Pretty => Ok ( Arg :: Pretty ( meta. span ( ) , true ) ) ,
117
148
ArgName :: Logging => Ok ( Arg :: Logging ( meta. span ( ) , true ) ) ,
118
-
119
149
ArgName :: PrefixEnter => Err ( prefix_enter_type_error ( ) ) ,
120
150
ArgName :: PrefixExit => Err ( prefix_exit_type_error ( ) ) ,
121
151
ArgName :: Enable => Err ( enable_type_error ( ) ) ,
122
152
ArgName :: Disable => Err ( disable_type_error ( ) ) ,
153
+ ArgName :: FormatEnter => Err ( format_enter_type_error ( ) ) ,
154
+ ArgName :: FormatExit => Err ( format_exit_type_error ( ) ) ,
123
155
} ,
124
156
syn:: Meta :: List ( syn:: MetaList { ref nested, .. } ) => match arg_name {
125
157
ArgName :: Enable => {
@@ -172,27 +204,14 @@ impl Args {
172
204
ArgName :: Pause => Err ( pause_type_error ( ) ) ,
173
205
ArgName :: Pretty => Err ( pretty_type_error ( ) ) ,
174
206
ArgName :: Logging => Err ( logging_type_error ( ) ) ,
207
+ ArgName :: FormatEnter => Err ( format_enter_type_error ( ) ) ,
208
+ ArgName :: FormatExit => Err ( format_exit_type_error ( ) ) ,
175
209
} ,
176
210
syn:: Meta :: NameValue ( syn:: MetaNameValue { ref lit, .. } ) => match arg_name {
177
- ArgName :: PrefixEnter => match * lit {
178
- syn:: Lit :: Str ( ref lit_str) => {
179
- Ok ( Arg :: PrefixEnter ( meta. span ( ) , lit_str. value ( ) ) )
180
- }
181
- _ => Err ( vec ! [ syn:: Error :: new_spanned(
182
- lit,
183
- "`prefix_enter` must have a string value" ,
184
- ) ] ) ,
185
- } ,
186
- ArgName :: PrefixExit => match * lit {
187
- syn:: Lit :: Str ( ref lit_str) => {
188
- Ok ( Arg :: PrefixExit ( meta. span ( ) , lit_str. value ( ) ) )
189
- }
190
- _ => Err ( vec ! [ syn:: Error :: new_spanned(
191
- lit,
192
- "`prefix_exit` must have a string value" ,
193
- ) ] ) ,
194
- } ,
195
-
211
+ ArgName :: PrefixEnter => try_extract_str ! ( lit, meta, PrefixEnter ) ,
212
+ ArgName :: PrefixExit => try_extract_str ! ( lit, meta, PrefixExit ) ,
213
+ ArgName :: FormatEnter => try_extract_str ! ( lit, meta, FormatEnter ) ,
214
+ ArgName :: FormatExit => try_extract_str ! ( lit, meta, FormatExit ) ,
196
215
ArgName :: Enable => Err ( enable_type_error ( ) ) ,
197
216
ArgName :: Disable => Err ( disable_type_error ( ) ) ,
198
217
ArgName :: Pause => Err ( pause_type_error ( ) ) ,
@@ -209,6 +228,8 @@ impl Args {
209
228
210
229
let mut prefix_enter_args = vec ! [ ] ;
211
230
let mut prefix_exit_args = vec ! [ ] ;
231
+ let mut format_enter_args = vec ! [ ] ;
232
+ let mut format_exit_args = vec ! [ ] ;
212
233
let mut enable_args = vec ! [ ] ;
213
234
let mut disable_args = vec ! [ ] ;
214
235
let mut pause_args = vec ! [ ] ;
@@ -227,6 +248,8 @@ impl Args {
227
248
Arg :: Pause ( span, b) => pause_args. push ( ( span, b) ) ,
228
249
Arg :: Pretty ( span, b) => pretty_args. push ( ( span, b) ) ,
229
250
Arg :: Logging ( span, b) => logging_args. push ( ( span, b) ) ,
251
+ Arg :: FormatEnter ( span, s) => format_enter_args. push ( ( span, s) ) ,
252
+ Arg :: FormatExit ( span, s) => format_exit_args. push ( ( span, s) ) ,
230
253
} ,
231
254
Err ( es) => errors. extend ( es) ,
232
255
}
@@ -247,6 +270,20 @@ impl Args {
247
270
. map ( |( span, _) | syn:: Error :: new ( * span, "duplicate `prefix_exit`" ) ) ,
248
271
) ;
249
272
}
273
+ if format_enter_args. len ( ) >= 2 {
274
+ errors. extend (
275
+ format_enter_args
276
+ . iter ( )
277
+ . map ( |( span, _) | syn:: Error :: new ( * span, "duplicate `format_enter`" ) ) ,
278
+ ) ;
279
+ }
280
+ if format_exit_args. len ( ) >= 2 {
281
+ errors. extend (
282
+ format_exit_args
283
+ . iter ( )
284
+ . map ( |( span, _) | syn:: Error :: new ( * span, "duplicate `format_exit`" ) ) ,
285
+ ) ;
286
+ }
250
287
if enable_args. len ( ) >= 2 {
251
288
errors. extend (
252
289
enable_args
@@ -294,6 +331,26 @@ impl Args {
294
331
"cannot have both `enable` and `disable`" ,
295
332
) ) ;
296
333
}
334
+ if pretty_args. len ( ) == 1 && format_enter_args. len ( ) == 1 {
335
+ errors. push ( syn:: Error :: new (
336
+ pretty_args[ 0 ] . 0 ,
337
+ "cannot have both `pretty` and `format_enter`" ,
338
+ ) ) ;
339
+ errors. push ( syn:: Error :: new (
340
+ format_enter_args[ 0 ] . 0 ,
341
+ "cannot have both `pretty` and `format_enter`" ,
342
+ ) ) ;
343
+ }
344
+ if pretty_args. len ( ) == 1 && format_exit_args. len ( ) == 1 {
345
+ errors. push ( syn:: Error :: new (
346
+ pretty_args[ 0 ] . 0 ,
347
+ "cannot have both `pretty` and `format_exit`" ,
348
+ ) ) ;
349
+ errors. push ( syn:: Error :: new (
350
+ format_exit_args[ 0 ] . 0 ,
351
+ "cannot have both `pretty` and `format_exit`" ,
352
+ ) ) ;
353
+ }
297
354
298
355
if errors. is_empty ( ) {
299
356
macro_rules! first_no_span {
@@ -306,6 +363,8 @@ impl Args {
306
363
. unwrap_or_else ( || DEFAULT_PREFIX_ENTER . to_owned ( ) ) ;
307
364
let prefix_exit =
308
365
first_no_span ! ( prefix_exit_args) . unwrap_or_else ( || DEFAULT_PREFIX_EXIT . to_owned ( ) ) ;
366
+ let format_enter = first_no_span ! ( format_enter_args) ;
367
+ let format_exit = first_no_span ! ( format_exit_args) ;
309
368
let filter = match ( first_no_span ! ( enable_args) , first_no_span ! ( disable_args) ) {
310
369
( None , None ) => Filter :: None ,
311
370
( Some ( idents) , None ) => Filter :: Enable ( idents) ,
@@ -323,6 +382,8 @@ impl Args {
323
382
pause,
324
383
pretty,
325
384
logging,
385
+ format_enter,
386
+ format_exit,
326
387
} )
327
388
} else {
328
389
Err ( errors)
0 commit comments