Skip to content

Subcommands #46

@Kixunil

Description

@Kixunil

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 have Subcmdname { config: subcmdname::Config, subcmd: subcmdname::Subcommand }, then matching code can just ignore empty struct. This obviously implies "outside" for the question about.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or requesthelp wantedExtra attention is neededv1.0These issues must be resolved before 1.0 release

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions