@@ -42,6 +42,15 @@ pub enum MissingFieldKind {
4242 ConfigField ,
4343}
4444
45+ /// A available subcommand name and its doc summary.
46+ #[ derive( Debug , Clone ) ]
47+ pub struct AvailableSubcommand {
48+ /// CLI name (kebab-case)
49+ pub name : String ,
50+ /// Doc summary if available
51+ pub doc : Option < String > ,
52+ }
53+
4554/// Information about a missing required field.
4655#[ derive( Debug , Clone ) ]
4756pub struct MissingFieldInfo {
@@ -61,6 +70,9 @@ pub struct MissingFieldInfo {
6170 pub env_aliases : Vec < String > ,
6271 /// What kind of field this is - determines error formatting strategy
6372 pub kind : MissingFieldKind ,
73+ /// If this field is a subcommand, the available subcommands.
74+ /// Non-empty only when the missing field is a subcommand field.
75+ pub available_subcommands : Vec < AvailableSubcommand > ,
6476}
6577
6678/// Information about a corrected command with missing arguments for display.
@@ -189,6 +201,7 @@ pub fn collect_missing_fields(
189201 env_var : None ,
190202 env_aliases : Vec :: new ( ) ,
191203 kind : MissingFieldKind :: ConfigField ,
204+ available_subcommands : Vec :: new ( ) ,
192205 } ) ;
193206 }
194207 } else {
@@ -230,6 +243,7 @@ fn collect_missing_in_arg_level(
230243 env_var : None , // CLI args don't have env vars
231244 env_aliases : Vec :: new ( ) ,
232245 kind : MissingFieldKind :: CliArg ,
246+ available_subcommands : Vec :: new ( ) ,
233247 } ) ;
234248 }
235249 }
@@ -243,6 +257,16 @@ fn collect_missing_in_arg_level(
243257 } else {
244258 format ! ( "{}.{}" , path_prefix, subcommand_field)
245259 } ;
260+
261+ let available_subcommands: Vec < AvailableSubcommand > = arg_level
262+ . subcommands ( )
263+ . iter ( )
264+ . map ( |( _, sub) | AvailableSubcommand {
265+ name : sub. cli_name ( ) . to_string ( ) ,
266+ doc : sub. docs ( ) . summary ( ) . map ( |s| s. to_string ( ) ) ,
267+ } )
268+ . collect ( ) ;
269+
246270 missing. push ( MissingFieldInfo {
247271 field_name : subcommand_field. to_string ( ) ,
248272 field_path,
@@ -252,6 +276,7 @@ fn collect_missing_in_arg_level(
252276 env_var : None ,
253277 env_aliases : Vec :: new ( ) ,
254278 kind : MissingFieldKind :: CliArg ,
279+ available_subcommands,
255280 } ) ;
256281 } else if let Some ( ConfigValue :: Enum ( sourced) ) = obj_map. get ( subcommand_field) {
257282 // Subcommand is present - recursively check its arguments
@@ -411,6 +436,7 @@ fn collect_missing_in_config_value(
411436 env_var : None ,
412437 env_aliases : field_schema. env_aliases ( ) . to_vec ( ) ,
413438 kind : MissingFieldKind :: ConfigField ,
439+ available_subcommands : Vec :: new ( ) ,
414440 } ) ;
415441 }
416442 }
@@ -493,6 +519,7 @@ fn check_missing_field(
493519 env_var,
494520 env_aliases : field_schema. env_aliases ( ) . to_vec ( ) ,
495521 kind : MissingFieldKind :: ConfigField ,
522+ available_subcommands : Vec :: new ( ) ,
496523 } ) ;
497524 }
498525}
0 commit comments