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 if at := name.index('=') {39 inline = name[at + 1..]40 name = name[..at]41 }42 if name in spec.values {43 mut value := inline44 if value == '' {45 index++46 if index >= raw.len {47 return error('--${name} needs a value')48 }49 value = raw[index]50 }51 args.values[name] = value52 args.multi[name] << value53 } else if name in spec.flags {54 if inline != '' {55 return error('--${name} takes no value')56 }57 args.flags[name] = true58 } else {59 return error('unknown option "--${name}" for "koh ${command}"')60 }61 } else if item.starts_with('-') && item.len > 1 {62 return error('unknown option "${item}" for "koh ${command}"')63 } else {64 args.positional << item65 }66 index++67 }68 return args69}7071pub fn (args &Args) flag(name string) bool {72 return args.flags[name]73}7475pub fn (args &Args) value(name string) string {76 return args.values[name] or { '' }77}78798081pub fn (args &Args) values_of(name string) []string {82 return args.multi[name] or { []string{} }83}8485pub fn (args &Args) value_or_none(name string) ?string {86 if name in args.values {87 return args.values[name]88 }89 return none90}9192pub fn (args &Args) json() bool {93 return args.flag('json')94}959697pub fn (args &Args) positional_at(index int) string {98 if index >= args.positional.len {99 return ''100 }101 return args.positional[index]102}