Provide helper for automatic getOpt error handling
This commit is contained in:
parent
3d5f1f70ff
commit
06633d9acd
2 changed files with 64 additions and 14 deletions
|
@ -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] ?? "",
|
||||
}));
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { AsText, TextPiece } from "../words";
|
||||
import { AsText, ErrorResult, ProcResult, TextPiece } from "../words";
|
||||
|
||||
export type Options = Record<string, number> & {
|
||||
$min?: number;
|
||||
|
@ -14,20 +14,66 @@ type ParsedOptions<P extends Options> = {
|
|||
error?: string;
|
||||
};
|
||||
|
||||
export function getOpt<P extends Options>(
|
||||
argv: TextPiece[],
|
||||
options: P,
|
||||
procBody: (switches: ParsedOptions<P>, ...argv: string[]) => ProcResult
|
||||
): ProcResult;
|
||||
export function getOpt<P extends Options>(
|
||||
argv: TextPiece[],
|
||||
options: P
|
||||
): [ParsedOptions<P>, ...string[]] {
|
||||
const [flags, textPieces] = getOptRaw(argv, options);
|
||||
return [flags, ...textPieces.map(AsText)];
|
||||
): [ParsedOptions<P>, ...string[]];
|
||||
export function getOpt<P extends Options>(
|
||||
argv: TextPiece[],
|
||||
options: P,
|
||||
procBody?: (switches: ParsedOptions<P>, ...argv: string[]) => ProcResult
|
||||
): [ParsedOptions<P>, ...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<P extends Options>(
|
||||
argv: TextPiece[],
|
||||
options: P,
|
||||
procBody: (switches: ParsedOptions<P>, argv: TextPiece[]) => ProcResult
|
||||
): ProcResult;
|
||||
export function getOptRaw<P extends Options>(
|
||||
argv: TextPiece[],
|
||||
options: P
|
||||
): [ParsedOptions<P>, TextPiece[]];
|
||||
export function getOptRaw<P extends Options>(
|
||||
argv: TextPiece[],
|
||||
options: P,
|
||||
procBody?: (switches: ParsedOptions<P>, argv: TextPiece[]) => ProcResult
|
||||
): [ParsedOptions<P>, 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<P extends Options>(
|
||||
argv: TextPiece[],
|
||||
options: P
|
||||
): [ParsedOptions<P>, TextPiece[]] {
|
||||
const [cmd, ...words] = argv;
|
||||
const result: ParsedOptions<P> = Object.fromEntries(
|
||||
const [cmd, ...textPiece] = argv;
|
||||
const flags: ParsedOptions<P> = Object.fromEntries(
|
||||
Object.entries(options)
|
||||
.filter(([name]) => name != "$min" && name != "$max")
|
||||
.map(([name]) => [])
|
||||
|
@ -35,18 +81,22 @@ export function getOptRaw<P extends Options>(
|
|||
|
||||
// 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<P>,
|
||||
{
|
||||
error: `${AsText(cmd)}: Not enough arguments`,
|
||||
} as ParsedOptions<P>,
|
||||
[],
|
||||
];
|
||||
}
|
||||
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<P>,
|
||||
{
|
||||
error: `${AsText(cmd)}: Too many arguments`,
|
||||
} as ParsedOptions<P>,
|
||||
[],
|
||||
];
|
||||
}
|
||||
|
||||
return [result, words];
|
||||
return [flags, textPiece];
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue