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}2021pub fn parse(command string, raw []string, spec Options) !Args {22 mut args := Args{}23 mut index := 024 for index < raw.len {25 item := raw[index]26 if item == '--' {27 args.positional << raw[index + 1..]28 break29 }30 if item.starts_with('--') {31 mut name := item[2..]32 mut inline := ''33 if at := name.index('=') {34 inline = name[at + 1..]35 name = name[..at]36 }37 if name in spec.values {38 mut value := inline39 if value == '' {40 index++41 if index >= raw.len {42 return error('--${name} needs a value')43 }44 value = raw[index]45 }46 args.values[name] = value47 } else if name in spec.flags {48 if inline != '' {49 return error('--${name} takes no value')50 }51 args.flags[name] = true52 } else {53 return error('unknown option "--${name}" for "koh ${command}"')54 }55 } else if item.starts_with('-') && item.len > 1 {56 return error('unknown option "${item}" for "koh ${command}"')57 } else {58 args.positional << item59 }60 index++61 }62 return args63}6465pub fn (args &Args) flag(name string) bool {66 return args.flags[name]67}6869pub fn (args &Args) value(name string) string {70 return args.values[name] or { '' }71}7273pub fn (args &Args) value_or_none(name string) ?string {74 if name in args.values {75 return args.values[name]76 }77 return none78}7980pub fn (args &Args) json() bool {81 return args.flag('json')82}838485pub fn (args &Args) positional_at(index int) string {86 if index >= args.positional.len {87 return ''88 }89 return args.positional[index]90}