1
1
//! Helpers for writing generators
2
2
3
- use clap:: { Arg , Command } ;
3
+ use clap:: { builder :: StyledStr , Arg , Command } ;
4
4
5
5
/// Gets all subcommands including child subcommands in the form of `("name", "bin_name")`.
6
6
///
7
7
/// Subcommand `rustup toolchain install` would be converted to
8
8
/// `("install", "rustup toolchain install")`.
9
- pub fn all_subcommands ( cmd : & Command ) -> Vec < ( String , String ) > {
9
+ pub fn all_subcommands ( cmd : & Command ) -> Vec < ( String , String , Option < StyledStr > ) > {
10
10
let mut subcmds: Vec < _ > = subcommands ( cmd) ;
11
11
12
12
for sc_v in cmd. get_subcommands ( ) . map ( all_subcommands) {
@@ -33,7 +33,7 @@ pub fn find_subcommand_with_path<'cmd>(p: &'cmd Command, path: Vec<&str>) -> &'c
33
33
///
34
34
/// Subcommand `rustup toolchain install` would be converted to
35
35
/// `("install", "rustup toolchain install")`.
36
- pub fn subcommands ( p : & Command ) -> Vec < ( String , String ) > {
36
+ pub fn subcommands ( p : & Command ) -> Vec < ( String , String , Option < StyledStr > ) > {
37
37
debug ! ( "subcommands: name={}" , p. get_name( ) ) ;
38
38
debug ! ( "subcommands: Has subcommands...{:?}" , p. has_subcommands( ) ) ;
39
39
@@ -48,62 +48,42 @@ pub fn subcommands(p: &Command) -> Vec<(String, String)> {
48
48
sc_bin_name
49
49
) ;
50
50
51
- subcmds. push ( ( sc. get_name ( ) . to_string ( ) , sc_bin_name. to_string ( ) ) ) ;
51
+ subcmds. push ( (
52
+ sc. get_name ( ) . to_string ( ) ,
53
+ sc_bin_name. to_string ( ) ,
54
+ sc. get_about ( ) . cloned ( ) ,
55
+ ) ) ;
52
56
}
53
57
54
58
subcmds
55
59
}
56
60
57
61
/// Gets all the short options, their visible aliases and flags of a [`clap::Command`].
58
62
/// Includes `h` and `V` depending on the [`clap::Command`] settings.
59
- pub fn shorts_and_visible_aliases ( p : & Command ) -> Vec < char > {
63
+ pub fn shorts_and_visible_aliases ( p : & Command ) -> Vec < ( char , Option < StyledStr > ) > {
60
64
debug ! ( "shorts: name={}" , p. get_name( ) ) ;
61
65
62
66
p. get_arguments ( )
63
67
. filter_map ( |a| {
64
- if !a. is_positional ( ) {
65
- if a. get_visible_short_aliases ( ) . is_some ( ) && a. get_short ( ) . is_some ( ) {
66
- let mut shorts_and_visible_aliases = a. get_visible_short_aliases ( ) . unwrap ( ) ;
67
- shorts_and_visible_aliases. push ( a. get_short ( ) . unwrap ( ) ) ;
68
- Some ( shorts_and_visible_aliases)
69
- } else if a. get_visible_short_aliases ( ) . is_none ( ) && a. get_short ( ) . is_some ( ) {
70
- Some ( vec ! [ a. get_short( ) . unwrap( ) ] )
71
- } else {
72
- None
73
- }
74
- } else {
75
- None
76
- }
68
+ a. get_short_and_visible_aliases ( )
69
+ . map ( |shorts| shorts. into_iter ( ) . map ( |s| ( s, a. get_help ( ) . cloned ( ) ) ) )
77
70
} )
78
71
. flatten ( )
79
72
. collect ( )
80
73
}
81
74
82
75
/// Gets all the long options, their visible aliases and flags of a [`clap::Command`].
83
76
/// Includes `help` and `version` depending on the [`clap::Command`] settings.
84
- pub fn longs_and_visible_aliases ( p : & Command ) -> Vec < String > {
77
+ pub fn longs_and_visible_aliases ( p : & Command ) -> Vec < ( String , Option < StyledStr > ) > {
85
78
debug ! ( "longs: name={}" , p. get_name( ) ) ;
86
79
87
80
p. get_arguments ( )
88
81
. filter_map ( |a| {
89
- if !a. is_positional ( ) {
90
- if a. get_visible_aliases ( ) . is_some ( ) && a. get_long ( ) . is_some ( ) {
91
- let mut visible_aliases: Vec < _ > = a
92
- . get_visible_aliases ( )
93
- . unwrap ( )
94
- . into_iter ( )
95
- . map ( |s| s. to_string ( ) )
96
- . collect ( ) ;
97
- visible_aliases. push ( a. get_long ( ) . unwrap ( ) . to_string ( ) ) ;
98
- Some ( visible_aliases)
99
- } else if a. get_visible_aliases ( ) . is_none ( ) && a. get_long ( ) . is_some ( ) {
100
- Some ( vec ! [ a. get_long( ) . unwrap( ) . to_string( ) ] )
101
- } else {
102
- None
103
- }
104
- } else {
105
- None
106
- }
82
+ a. get_long_and_visible_aliases ( ) . map ( |longs| {
83
+ longs
84
+ . into_iter ( )
85
+ . map ( |s| ( s. to_string ( ) , a. get_help ( ) . cloned ( ) ) )
86
+ } )
107
87
} )
108
88
. flatten ( )
109
89
. collect ( )
@@ -136,6 +116,19 @@ mod tests {
136
116
use clap:: Arg ;
137
117
use clap:: ArgAction ;
138
118
119
+ const HELP : & str = "Print this message or the help of the given subcommand(s)" ;
120
+
121
+ macro_rules! assert_option {
122
+ ( $option: expr, $value: expr) => {
123
+ assert_eq!( $option. 0 , $value) ;
124
+ assert!( $option. 1 . is_none( ) ) ;
125
+ } ;
126
+ ( $option: expr, $value: expr, $help: expr) => {
127
+ assert_eq!( $option. 0 , $value) ;
128
+ assert_eq!( $option. 1 . as_ref( ) . unwrap( ) . to_string( ) , $help) ;
129
+ } ;
130
+ }
131
+
139
132
fn common_app ( ) -> Command {
140
133
Command :: new ( "myapp" )
141
134
. subcommand (
@@ -171,36 +164,44 @@ mod tests {
171
164
fn test_subcommands ( ) {
172
165
let cmd = built_with_version ( ) ;
173
166
174
- assert_eq ! (
175
- subcommands( & cmd) ,
176
- vec![
177
- ( "test" . to_string( ) , "my-cmd test" . to_string( ) ) ,
178
- ( "hello" . to_string( ) , "my-cmd hello" . to_string( ) ) ,
179
- ( "help" . to_string( ) , "my-cmd help" . to_string( ) ) ,
180
- ]
181
- ) ;
167
+ for ( actual, expected) in subcommands ( & cmd) . into_iter ( ) . zip ( [
168
+ ( "test" , "my-cmd test" , None ) ,
169
+ ( "hello" , "my-cmd hello" , None ) ,
170
+ ( "help" , "my-cmd help" , Some ( HELP ) ) ,
171
+ ] ) {
172
+ assert_eq ! ( actual. 0 , expected. 0 ) ;
173
+ assert_eq ! ( actual. 1 , expected. 1 ) ;
174
+ assert_eq ! (
175
+ actual. 2 . as_ref( ) . map( ToString :: to_string) . as_deref( ) ,
176
+ expected. 2
177
+ ) ;
178
+ }
182
179
}
183
180
184
181
#[ test]
185
182
fn test_all_subcommands ( ) {
186
183
let cmd = built_with_version ( ) ;
187
184
188
- assert_eq ! (
189
- all_subcommands( & cmd) ,
190
- vec![
191
- ( "test" . to_string( ) , "my-cmd test" . to_string( ) ) ,
192
- ( "hello" . to_string( ) , "my-cmd hello" . to_string( ) ) ,
193
- ( "help" . to_string( ) , "my-cmd help" . to_string( ) ) ,
194
- ( "config" . to_string( ) , "my-cmd test config" . to_string( ) ) ,
195
- ( "help" . to_string( ) , "my-cmd test help" . to_string( ) ) ,
196
- ( "config" . to_string( ) , "my-cmd test help config" . to_string( ) ) ,
197
- ( "help" . to_string( ) , "my-cmd test help help" . to_string( ) ) ,
198
- ( "test" . to_string( ) , "my-cmd help test" . to_string( ) ) ,
199
- ( "hello" . to_string( ) , "my-cmd help hello" . to_string( ) ) ,
200
- ( "help" . to_string( ) , "my-cmd help help" . to_string( ) ) ,
201
- ( "config" . to_string( ) , "my-cmd help test config" . to_string( ) ) ,
202
- ]
203
- ) ;
185
+ for ( actual, expected) in subcommands ( & cmd) . into_iter ( ) . zip ( [
186
+ ( "test" , "my-cmd test" , None ) ,
187
+ ( "hello" , "my-cmd hello" , None ) ,
188
+ ( "help" , "my-cmd help" , Some ( HELP ) ) ,
189
+ ( "config" , "my-cmd test config" , None ) ,
190
+ ( "help" , "my-cmd test help" , Some ( HELP ) ) ,
191
+ ( "config" , "my-cmd test help config" , None ) ,
192
+ ( "help" , "my-cmd test help help" , Some ( HELP ) ) ,
193
+ ( "test" , "my-cmd help test" , None ) ,
194
+ ( "hello" , "my-cmd help hello" , None ) ,
195
+ ( "help" , "my-cmd help help" , Some ( HELP ) ) ,
196
+ ( "config" , "my-cmd help test config" , None ) ,
197
+ ] ) {
198
+ assert_eq ! ( actual. 0 , expected. 0 ) ;
199
+ assert_eq ! ( actual. 1 , expected. 1 ) ;
200
+ assert_eq ! (
201
+ actual. 2 . as_ref( ) . map( ToString :: to_string) . as_deref( ) ,
202
+ expected. 2
203
+ ) ;
204
+ }
204
205
}
205
206
206
207
#[ test]
@@ -248,15 +249,15 @@ mod tests {
248
249
let shorts = shorts_and_visible_aliases ( & cmd) ;
249
250
250
251
assert_eq ! ( shorts. len( ) , 2 ) ;
251
- assert_eq ! ( shorts[ 0 ] , 'h' ) ;
252
- assert_eq ! ( shorts[ 1 ] , 'V' ) ;
252
+ assert_option ! ( shorts[ 0 ] , 'h' , "Print help" ) ;
253
+ assert_option ! ( shorts[ 1 ] , 'V' , "Print version" ) ;
253
254
254
255
let sc_shorts = shorts_and_visible_aliases ( find_subcommand_with_path ( & cmd, vec ! [ "test" ] ) ) ;
255
256
256
257
assert_eq ! ( sc_shorts. len( ) , 3 ) ;
257
- assert_eq ! ( sc_shorts[ 0 ] , 'p ' ) ;
258
- assert_eq ! ( sc_shorts[ 1 ] , 'f ' ) ;
259
- assert_eq ! ( sc_shorts[ 2 ] , 'h' ) ;
258
+ assert_option ! ( sc_shorts[ 0 ] , 'f ' ) ;
259
+ assert_option ! ( sc_shorts[ 1 ] , 'p ' ) ;
260
+ assert_option ! ( sc_shorts[ 2 ] , 'h' , "Print help" ) ;
260
261
}
261
262
262
263
#[ test]
@@ -265,14 +266,14 @@ mod tests {
265
266
let longs = longs_and_visible_aliases ( & cmd) ;
266
267
267
268
assert_eq ! ( longs. len( ) , 2 ) ;
268
- assert_eq ! ( longs[ 0 ] , "help" ) ;
269
- assert_eq ! ( longs[ 1 ] , "version" ) ;
269
+ assert_option ! ( longs[ 0 ] , "help" , "Print help") ;
270
+ assert_option ! ( longs[ 1 ] , "version" , "Print version") ;
270
271
271
272
let sc_longs = longs_and_visible_aliases ( find_subcommand_with_path ( & cmd, vec ! [ "test" ] ) ) ;
272
273
273
274
assert_eq ! ( sc_longs. len( ) , 3 ) ;
274
- assert_eq ! ( sc_longs[ 0 ] , "path " ) ;
275
- assert_eq ! ( sc_longs[ 1 ] , "file " ) ;
276
- assert_eq ! ( sc_longs[ 2 ] , "help" ) ;
275
+ assert_option ! ( sc_longs[ 0 ] , "file " ) ;
276
+ assert_option ! ( sc_longs[ 1 ] , "path " ) ;
277
+ assert_option ! ( sc_longs[ 2 ] , "help" , "Print help") ;
277
278
}
278
279
}
0 commit comments