args.v

2.0 KB · raw

1//! Command line parsing.2//!3//! Each command declares the options it takes, so a typo is refused with a4//! usage error instead of being ignored — an agent's mistake should be loud.56module cli78pub struct Options {9pub:10	values []string // options that take a value11	flags  []string // options that take none12}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}8384// positional_at returns the argument at `index`, or '' when it is missing.85pub fn (args &Args) positional_at(index int) string {86	if index >= args.positional.len {87		return ''88	}89	return args.positional[index]90}