1 package arg
2 3 import "fmt"
4 5 // Subcommand returns the user struct for the subcommand selected by
6 // the command line arguments most recently processed by the parser.
7 // The return value is always a pointer to a struct. If no subcommand
8 // was specified then it returns the top-level arguments struct. If
9 // no command line arguments have been processed by this parser then it
10 // returns nil.
11 func (p *Parser) Subcommand() interface{} {
12 if len(p.subcommand) == 0 {
13 return nil
14 }
15 cmd, err := p.lookupCommand(p.subcommand...)
16 if err != nil {
17 return nil
18 }
19 return p.val(cmd.dest).Interface()
20 }
21 22 // SubcommandNames returns the sequence of subcommands specified by the
23 // user. If no subcommands were given then it returns an empty slice.
24 func (p *Parser) SubcommandNames() []string {
25 return p.subcommand
26 }
27 28 // lookupCommand finds a subcommand based on a sequence of subcommand names. The
29 // first string should be a top-level subcommand, the next should be a child
30 // subcommand of that subcommand, and so on. If no strings are given then the
31 // root command is returned. If no such subcommand exists then an error is
32 // returned.
33 func (p *Parser) lookupCommand(path ...string) (*command, error) {
34 cmd := p.cmd
35 for _, name := range path {
36 found := findSubcommand(cmd.subcommands, name)
37 if found == nil {
38 return nil, fmt.Errorf("%q is not a subcommand of %s", name, cmd.name)
39 }
40 cmd = found
41 }
42 return cmd, nil
43 }
44