Subcommands
Opened this issue · 0 comments
Kixunil commented
Support subcommands like e.g. commit
is a subcommand of git
.
Example input:
[general]
# global options
# This is a global param - given to program in the form of cmd --foo subcmd
# We could later support cmd subcmd --foo
[[param]]
name = "foo"
type = "String"
# ...
# same as above an be done with switch
# We use subcmd instead of subcommand to keep it reasonably short because it will be repeated
[subcmd.subcmdname.general]
# Only support these two for now, other things available above are mostly non-sensical here
summary = "This command does something"
doc = "Long explanation of what this command is all about..."
# LATER we could also support include = "file-relative-to-current"
# included files should probably only support params and switches
# works exactly the same as in top-level
[[subcmd.subcmdname.param]]
name = "bar"
type = "String"
# switch is supported here as well
# nested subcommand is also supported
The generated code will look something like this:
enum Subcommand {
Subcmdname(subcmdname::Config),
}
// recursively generates almost the same thing as top-level
mod subcmdname {
struct Config {
// no _program_name here, it's pointless
bar: String,
}
// also has raw module like the top-level
mod raw {
}
}
Specification parsing code will get subcmd: HashMap<Ident, Subcommand>
field.
struct Subcommand {
global: SubcommandGlobal,
param: Vec<Param>,
switch: Vec<Switch>,
}
Difficult stuff:
- How to parse and process config files for subcommands? Suggestion: don't support in initial impl
- How to process env vars for config files? Suggestion: don't support in initial impl
- Should subcommand be inside
Config
, or outside? The advantage of being outside is it can get global config without self-reference but maybe that's not useful as immutable references will most likely be used? - Should we support more straightforward design as
clap
does? If there are multiple nested subcommands and mid-commmands don't have any options, then avoiding the struct would lead to easier-to-write code, although harder-to-refactor. Maybe instead haveSubcmdname { config: subcmdname::Config, subcmd: subcmdname::Subcommand }
, then matching code can just ignore empty struct. This obviously implies "outside" for the question about.