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}2324pub fn parse(command string, raw []string, spec Options) !Args {25 mut args := Args{}26 mut index := 027 for index < raw.len {28 item := raw[index]29 if item == '--' {30 args.positional << raw[index + 1..]31 break32 }33 if item.starts_with('--') {34 mut name := item[2..]35 mut inline := ''36 if at := name.index('=') {37 inline = name[at + 1..]38 name = name[..at]39 }40 if name in spec.values {41 mut value := inline42 if value == '' {43 index++44 if index >= raw.len {45 return error('--${name} needs a value')46 }47 value = raw[index]48 }49 args.values[name] = value50 args.multi[name] << value51 } else if name in spec.flags {52 if inline != '' {53 return error('--${name} takes no value')54 }55 args.flags[name] = true56 } else {57 return error('unknown option "--${name}" for "koh ${command}"')58 }59 } else if item.starts_with('-') && item.len > 1 {60 return error('unknown option "${item}" for "koh ${command}"')61 } else {62 args.positional << item63 }64 index++65 }66 return args67}6869pub fn (args &Args) flag(name string) bool {70 return args.flags[name]71}7273pub fn (args &Args) value(name string) string {74 return args.values[name] or { '' }75}76777879pub fn (args &Args) values_of(name string) []string {80 return args.multi[name] or { []string{} }81}8283pub fn (args &Args) value_or_none(name string) ?string {84 if name in args.values {85 return args.values[name]86 }87 return none88}8990pub fn (args &Args) json() bool {91 return args.flag('json')92}939495pub fn (args &Args) positional_at(index int) string {96 if index >= args.positional.len {97 return ''98 }99 return args.positional[index]100}