1package cli
2
3// CommandCategories interface allows for category manipulation
4type CommandCategories interface {
5	// AddCommand adds a command to a category, creating a new category if necessary.
6	AddCommand(category string, command *Command)
7	// categories returns a copy of the category slice
8	Categories() []CommandCategory
9}
10
11type commandCategories []*commandCategory
12
13func newCommandCategories() CommandCategories {
14	ret := commandCategories([]*commandCategory{})
15	return &ret
16}
17
18func (c *commandCategories) Less(i, j int) bool {
19	return lexicographicLess((*c)[i].Name(), (*c)[j].Name())
20}
21
22func (c *commandCategories) Len() int {
23	return len(*c)
24}
25
26func (c *commandCategories) Swap(i, j int) {
27	(*c)[i], (*c)[j] = (*c)[j], (*c)[i]
28}
29
30func (c *commandCategories) AddCommand(category string, command *Command) {
31	for _, commandCategory := range []*commandCategory(*c) {
32		if commandCategory.name == category {
33			commandCategory.commands = append(commandCategory.commands, command)
34			return
35		}
36	}
37	newVal := append(*c,
38		&commandCategory{name: category, commands: []*Command{command}})
39	*c = newVal
40}
41
42func (c *commandCategories) Categories() []CommandCategory {
43	ret := make([]CommandCategory, len(*c))
44	for i, cat := range *c {
45		ret[i] = cat
46	}
47	return ret
48}
49
50// CommandCategory is a category containing commands.
51type CommandCategory interface {
52	// Name returns the category name string
53	Name() string
54	// VisibleCommands returns a slice of the Commands with Hidden=false
55	VisibleCommands() []*Command
56}
57
58type commandCategory struct {
59	name     string
60	commands []*Command
61}
62
63func (c *commandCategory) Name() string {
64	return c.name
65}
66
67func (c *commandCategory) VisibleCommands() []*Command {
68	if c.commands == nil {
69		c.commands = []*Command{}
70	}
71
72	var ret []*Command
73	for _, command := range c.commands {
74		if !command.Hidden {
75			ret = append(ret, command)
76		}
77	}
78	return ret
79}
80