123456module cli78pub struct Options {9pub:10 values []string 11 flags []string 12}1314pub struct Args {15pub mut:16 positional []string17 values map[string]string18 flags map[string]bool19 20 21 multi map[string][]string22}23242526pub fn parse(command string, raw []string, spec Options) !Args {27 mut args := Args{}28 mut index := 029 for index < raw.len {30 item := raw[index]31 if item == '--' {32 args.positional << raw[index + 1..]33 break34 }35 if item.starts_with('--') {36 mut name := item[2..]37 mut inline := ''38 mut has_inline := false39 if at := name.index('=') {40 inline = name[at + 1..]41 name = name[..at]42 has_inline = true43 }44 if name in spec.values {45 mut value := inline46 if !has_inline {47 index++48 if index >= raw.len {49 return error('--${name} needs a value')50 }51 value = raw[index]52 }53 args.values[name] = value54 args.multi[name] << value55 } else if name in spec.flags {56 if has_inline {57 return error('--${name} takes no value')58 }59 args.flags[name] = true60 } else {61 return error('unknown option "--${name}" for "koh ${command}"')62 }63 } else if item.starts_with('-') && item.len > 1 {64 return error('unknown option "${item}" for "koh ${command}"')65 } else {66 args.positional << item67 }68 index++69 }70 return args71}7273pub fn (args &Args) flag(name string) bool {74 return args.flags[name]75}7677pub fn (args &Args) value(name string) string {78 return args.values[name] or { '' }79}80818283pub fn (args &Args) values_of(name string) []string {84 return args.multi[name] or { []string{} }85}8687pub fn (args &Args) value_or_none(name string) ?string {88 if name in args.values {89 return args.values[name]90 }91 return none92}9394pub fn (args &Args) json() bool {95 return args.flag('json')96}979899pub fn (args &Args) positional_at(index int) string {100 if index >= args.positional.len {101 return ''102 }103 return args.positional[index]104}