@@ -15,7 +15,9 @@ use heck::{CamelCase, KebabCase, MixedCase, ShoutySnakeCase, SnakeCase};
15
15
use proc_macro2:: { Span , TokenStream } ;
16
16
use proc_macro_error:: abort;
17
17
use quote:: { quote, quote_spanned, ToTokens } ;
18
- use syn:: { self , ext:: IdentExt , spanned:: Spanned , Attribute , Expr , Ident , LitStr , MetaNameValue } ;
18
+ use syn:: {
19
+ self , ext:: IdentExt , spanned:: Spanned , Attribute , Expr , Ident , LitStr , MetaNameValue , Type ,
20
+ } ;
19
21
20
22
#[ derive( Clone ) ]
21
23
pub enum Kind {
@@ -75,6 +77,7 @@ pub struct Attrs {
75
77
name : Name ,
76
78
casing : Sp < CasingStyle > ,
77
79
env_casing : Sp < CasingStyle > ,
80
+ ty : Option < Type > ,
78
81
doc_comment : Vec < Method > ,
79
82
methods : Vec < Method > ,
80
83
parser : Sp < Parser > ,
@@ -215,11 +218,13 @@ impl Attrs {
215
218
fn new (
216
219
default_span : Span ,
217
220
name : Name ,
221
+ ty : Option < Type > ,
218
222
casing : Sp < CasingStyle > ,
219
223
env_casing : Sp < CasingStyle > ,
220
224
) -> Self {
221
225
Self {
222
226
name,
227
+ ty,
223
228
casing,
224
229
env_casing,
225
230
doc_comment : vec ! [ ] ,
@@ -285,6 +290,31 @@ impl Attrs {
285
290
286
291
VerbatimDocComment ( ident) => self . verbatim_doc_comment = Some ( ident) ,
287
292
293
+ DefaultValue ( ident, lit) => {
294
+ let val = if let Some ( lit) = lit {
295
+ quote ! ( #lit)
296
+ } else {
297
+ let ty = if let Some ( ty) = self . ty . as_ref ( ) {
298
+ ty
299
+ } else {
300
+ abort ! (
301
+ ident. span( ) ,
302
+ "#[structopt(default_value)] (without an argument) can be used \
303
+ only on field level";
304
+
305
+ note = "see \
306
+ https://docs.rs/structopt/0.3.5/structopt/#magical-methods")
307
+ } ;
308
+ quote_spanned ! ( ident. span( ) => {
309
+ let val = <#ty as :: std:: default :: Default >:: default ( ) ;
310
+ let s = :: std:: string:: ToString :: to_string( & val) ;
311
+ :: std:: boxed:: Box :: leak( s. into_boxed_str( ) )
312
+ } )
313
+ } ;
314
+
315
+ self . methods . push ( Method :: new ( ident, val) ) ;
316
+ }
317
+
288
318
About ( ident, about) => {
289
319
self . about = Method :: from_lit_or_env ( ident, about, "CARGO_PKG_DESCRIPTION" ) ;
290
320
}
@@ -350,7 +380,7 @@ impl Attrs {
350
380
argument_casing : Sp < CasingStyle > ,
351
381
env_casing : Sp < CasingStyle > ,
352
382
) -> Self {
353
- let mut res = Self :: new ( span, name, argument_casing, env_casing) ;
383
+ let mut res = Self :: new ( span, name, None , argument_casing, env_casing) ;
354
384
res. push_attrs ( attrs) ;
355
385
res. push_doc_comment ( attrs, "about" ) ;
356
386
@@ -377,6 +407,7 @@ impl Attrs {
377
407
let mut res = Self :: new (
378
408
field. span ( ) ,
379
409
Name :: Derived ( name. clone ( ) ) ,
410
+ Some ( field. ty . clone ( ) ) ,
380
411
struct_casing,
381
412
env_casing,
382
413
) ;
0 commit comments