|
1 | 1 | package sdk |
2 | 2 |
|
3 | | -import "memex/pkg/types" |
| 3 | +import ( |
| 4 | + "fmt" |
| 5 | + "memex/pkg/types" |
| 6 | +) |
4 | 7 |
|
5 | 8 | // CommandBuilder helps build commands with a fluent interface |
6 | 9 | type CommandBuilder struct { |
@@ -39,48 +42,111 @@ func (b *CommandBuilder) Build() types.Command { |
39 | 42 | return b.cmd |
40 | 43 | } |
41 | 44 |
|
| 45 | +// CommandHandler represents a function that handles a command |
| 46 | +type CommandHandler func(repo types.Repository, args []string) error |
| 47 | + |
| 48 | +// CommandSet represents a set of commands with their handlers |
| 49 | +type CommandSet struct { |
| 50 | + commands map[string]types.Command |
| 51 | + handlers map[string]CommandHandler |
| 52 | +} |
| 53 | + |
| 54 | +// NewCommandSet creates a new command set |
| 55 | +func NewCommandSet() *CommandSet { |
| 56 | + return &CommandSet{ |
| 57 | + commands: make(map[string]types.Command), |
| 58 | + handlers: make(map[string]CommandHandler), |
| 59 | + } |
| 60 | +} |
| 61 | + |
| 62 | +// Add adds a command and its handler to the set |
| 63 | +func (cs *CommandSet) Add(cmd types.Command, handler CommandHandler) { |
| 64 | + cs.commands[cmd.Name] = cmd |
| 65 | + cs.handlers[cmd.Name] = handler |
| 66 | +} |
| 67 | + |
| 68 | +// Get returns a command and its handler by name |
| 69 | +func (cs *CommandSet) Get(name string) (types.Command, CommandHandler, bool) { |
| 70 | + cmd, exists := cs.commands[name] |
| 71 | + if !exists { |
| 72 | + return types.Command{}, nil, false |
| 73 | + } |
| 74 | + return cmd, cs.handlers[name], true |
| 75 | +} |
| 76 | + |
| 77 | +// List returns all commands in the set |
| 78 | +func (cs *CommandSet) List() []types.Command { |
| 79 | + cmds := make([]types.Command, 0, len(cs.commands)) |
| 80 | + for _, cmd := range cs.commands { |
| 81 | + cmds = append(cmds, cmd) |
| 82 | + } |
| 83 | + return cmds |
| 84 | +} |
| 85 | + |
| 86 | +// Handle executes a command with the given arguments |
| 87 | +func (cs *CommandSet) Handle(repo types.Repository, cmd string, args []string) error { |
| 88 | + _, handler, exists := cs.Get(cmd) |
| 89 | + if !exists { |
| 90 | + return fmt.Errorf("%w: command %s", ErrNotFound, cmd) |
| 91 | + } |
| 92 | + return handler(repo, args) |
| 93 | +} |
| 94 | + |
42 | 95 | // Common command patterns |
43 | 96 |
|
44 | 97 | // NewAddCommand creates a standard add command |
45 | | -func NewAddCommand(itemType string) types.Command { |
46 | | - return NewCommand("add"). |
| 98 | +func NewAddCommand(itemType string, handler CommandHandler) (types.Command, CommandHandler) { |
| 99 | + cmd := NewCommand("add"). |
47 | 100 | WithDescription("Add " + itemType). |
48 | 101 | WithUsage("add <" + itemType + ">"). |
49 | 102 | WithArgs(itemType). |
50 | 103 | Build() |
| 104 | + return cmd, handler |
51 | 105 | } |
52 | 106 |
|
53 | 107 | // NewListCommand creates a standard list command |
54 | | -func NewListCommand(itemType string) types.Command { |
55 | | - return NewCommand("list"). |
| 108 | +func NewListCommand(itemType string, handler CommandHandler) (types.Command, CommandHandler) { |
| 109 | + cmd := NewCommand("list"). |
56 | 110 | WithDescription("List " + itemType + "s"). |
57 | 111 | WithUsage("list [filter]"). |
58 | 112 | Build() |
| 113 | + return cmd, handler |
59 | 114 | } |
60 | 115 |
|
61 | 116 | // NewRemoveCommand creates a standard remove command |
62 | | -func NewRemoveCommand(itemType string) types.Command { |
63 | | - return NewCommand("remove"). |
| 117 | +func NewRemoveCommand(itemType string, handler CommandHandler) (types.Command, CommandHandler) { |
| 118 | + cmd := NewCommand("remove"). |
64 | 119 | WithDescription("Remove " + itemType). |
65 | 120 | WithUsage("remove <" + itemType + ">"). |
66 | 121 | WithArgs(itemType). |
67 | 122 | Build() |
| 123 | + return cmd, handler |
68 | 124 | } |
69 | 125 |
|
70 | 126 | // NewShowCommand creates a standard show command |
71 | | -func NewShowCommand(itemType string) types.Command { |
72 | | - return NewCommand("show"). |
| 127 | +func NewShowCommand(itemType string, handler CommandHandler) (types.Command, CommandHandler) { |
| 128 | + cmd := NewCommand("show"). |
73 | 129 | WithDescription("Show " + itemType + " details"). |
74 | 130 | WithUsage("show <" + itemType + ">"). |
75 | 131 | WithArgs(itemType). |
76 | 132 | Build() |
| 133 | + return cmd, handler |
77 | 134 | } |
78 | 135 |
|
79 | 136 | // NewUpdateCommand creates a standard update command |
80 | | -func NewUpdateCommand(itemType string) types.Command { |
81 | | - return NewCommand("update"). |
| 137 | +func NewUpdateCommand(itemType string, handler CommandHandler) (types.Command, CommandHandler) { |
| 138 | + cmd := NewCommand("update"). |
82 | 139 | WithDescription("Update " + itemType). |
83 | 140 | WithUsage("update <" + itemType + "> [options]"). |
84 | 141 | WithArgs(itemType). |
85 | 142 | Build() |
| 143 | + return cmd, handler |
| 144 | +} |
| 145 | + |
| 146 | +// ValidateArgs validates command arguments |
| 147 | +func ValidateArgs(cmd types.Command, args []string) error { |
| 148 | + if len(args) < len(cmd.Args) { |
| 149 | + return fmt.Errorf("%w: missing required arguments: %v", ErrInvalidInput, cmd.Args[len(args):]) |
| 150 | + } |
| 151 | + return nil |
86 | 152 | } |
0 commit comments