/ parser.go
parser.go
1 package dispatch2 2 3 import ( 4 "strings" 5 ) 6 7 // ParseCommand attempts to match a string with [Command.Name] or [Command.Aliases] 8 func parseCommand[Config any](cmds []Command[Config], cmd string) (found Command[Config], err error) { 9 if cmd == "" { 10 err = ErrCommandCannotParseEmptyString 11 /* 12 flag.Usage() 13 14 fmt.Println("") 15 PrintValidCommands(cmds) 16 */ 17 return 18 } 19 20 for _, command := range cmds { 21 if strings.EqualFold(cmd, command.Name()) { 22 found = command 23 } 24 25 if found != nil { 26 if found.Name() != "" { 27 break 28 } 29 } 30 31 for _, alias := range command.Aliases() { 32 if strings.EqualFold(cmd, alias) { 33 found = command 34 break 35 } 36 } 37 } 38 39 if found == nil { 40 err = ErrCommandNotFound 41 return 42 } 43 44 return 45 } 46 47 // ParseArgsForSubcommand parses the provided args cyclically through the 48 // [Command] slice and any associated subcommand, returning any error OR the 49 // final parsed [Command] and any remaining args. 50 func parseArgsForSubcommand[Config any](commands []Command[Config], args []string) (Command[Config], []string, error) { 51 switch nargs := len(args); nargs { 52 case 0: 53 /* 54 flag.Usage() 55 PrintValidCommands(commands) 56 57 return Command{}, nil, ErrCommandRequired 58 */ 59 60 return nil, nil, ErrCommandRequired 61 case 1: 62 command, err := parseCommand(commands, args[0]) 63 if err != nil { 64 return command, args, err 65 } 66 67 return command, nil, nil 68 default: 69 command, err := parseCommand(commands, args[0]) 70 if err != nil { 71 return command, nil, err 72 } 73 74 if command == nil { 75 return nil, nil, ErrCommandNil 76 } 77 78 if command.NSubcommands() == 0 { 79 return command, args[1:], nil 80 } 81 82 subcommand, argsLeft, err := parseArgsForSubcommand(command.Subcommands(), args[1:]) 83 if err != nil { 84 if err == ErrCommandNotFound { 85 return command, args[1:], nil 86 } 87 88 return command, nil, err 89 } 90 91 return subcommand, argsLeft, nil 92 } 93 }