diff --git a/src/lib/card.ts b/src/lib/card.ts index 79336ed..553596d 100644 --- a/src/lib/card.ts +++ b/src/lib/card.ts @@ -19,7 +19,7 @@ export type CardVm = Vm<{ }>; export function GetField(vm: CardVm, argv: TextPiece[]): ProcResult { - const [{ error }, fieldName] = getOpt(argv, { $min: 1, $max: 1 }); - if (error) return { error }; - return { text: vm.card.fields[fieldName] ?? error ?? "" }; + return getOpt(argv, { $min: 1, $max: 1 }, ({}, fieldName) => ({ + text: vm.card.fields[fieldName] ?? "", + })); } diff --git a/src/lib/options.ts b/src/lib/options.ts index 7843fc3..30f3aa0 100644 --- a/src/lib/options.ts +++ b/src/lib/options.ts @@ -1,4 +1,4 @@ -import { AsText, TextPiece } from "../words"; +import { AsText, ErrorResult, ProcResult, TextPiece } from "../words"; export type Options = Record & { $min?: number; @@ -14,20 +14,66 @@ type ParsedOptions

= { error?: string; }; +export function getOpt

( + argv: TextPiece[], + options: P, + procBody: (switches: ParsedOptions

, ...argv: string[]) => ProcResult +): ProcResult; export function getOpt

( argv: TextPiece[], options: P -): [ParsedOptions

, ...string[]] { - const [flags, textPieces] = getOptRaw(argv, options); - return [flags, ...textPieces.map(AsText)]; +): [ParsedOptions

, ...string[]]; +export function getOpt

( + argv: TextPiece[], + options: P, + procBody?: (switches: ParsedOptions

, ...argv: string[]) => ProcResult +): [ParsedOptions

, ...string[]] | ProcResult { + const [flags, textPieces] = getOptCore(argv, options); + + if (procBody) { + if ("error" in flags) { + return flags as ErrorResult; + } else { + return procBody(flags, ...textPieces.map(AsText)); + } + } else { + return [flags, ...textPieces.map(AsText)]; + } } export function getOptRaw

( + argv: TextPiece[], + options: P, + procBody: (switches: ParsedOptions

, argv: TextPiece[]) => ProcResult +): ProcResult; +export function getOptRaw

( + argv: TextPiece[], + options: P +): [ParsedOptions

, TextPiece[]]; +export function getOptRaw

( + argv: TextPiece[], + options: P, + procBody?: (switches: ParsedOptions

, argv: TextPiece[]) => ProcResult +): [ParsedOptions

, TextPiece[]] | ProcResult { + const [flags, textPieces] = getOptCore(argv, options); + + if (procBody) { + if ("error" in flags) { + return flags as ErrorResult; + } else { + return procBody(flags, textPieces); + } + } else { + return [flags, textPieces]; + } +} + +function getOptCore

( argv: TextPiece[], options: P ): [ParsedOptions

, TextPiece[]] { - const [cmd, ...words] = argv; - const result: ParsedOptions

= Object.fromEntries( + const [cmd, ...textPiece] = argv; + const flags: ParsedOptions

= Object.fromEntries( Object.entries(options) .filter(([name]) => name != "$min" && name != "$max") .map(([name]) => []) @@ -35,18 +81,22 @@ export function getOptRaw

( // TODO: parse switches - if (options.$min !== undefined && options.$min > words.length) { + if (options.$min !== undefined && options.$min > textPiece.length) { return [ - { error: `${AsText(cmd)}: Not enough arguments` } as ParsedOptions

, + { + error: `${AsText(cmd)}: Not enough arguments`, + } as ParsedOptions

, [], ]; } - if (options.$max !== undefined && options.$max < words.length) { + if (options.$max !== undefined && options.$max < textPiece.length) { return [ - { error: `${AsText(cmd)}: Too many arguments` } as ParsedOptions

, + { + error: `${AsText(cmd)}: Too many arguments`, + } as ParsedOptions

, [], ]; } - return [result, words]; + return [flags, textPiece]; }