From 55519c21af02b344fa9753111e3bf6f4975b0479 Mon Sep 17 00:00:00 2001 From: Elizabeth Hunt Date: Sat, 14 Jun 2025 12:27:04 -0700 Subject: Fix some logging stuff --- u/process/argv.ts | 118 ++++++++++++++++++++++++++++-------------------------- 1 file changed, 62 insertions(+), 56 deletions(-) (limited to 'u/process/argv.ts') diff --git a/u/process/argv.ts b/u/process/argv.ts index 8e85477..45f8ff0 100644 --- a/u/process/argv.ts +++ b/u/process/argv.ts @@ -1,66 +1,72 @@ -import { Either, type IEither } from "@emprespresso/pengueno"; +import { Either, type Mapper, type IEither } from "@emprespresso/pengueno"; export const isArgKey = (k: string): k is K => k.startsWith("--"); -export const getArg = ( +interface ArgHandler { + absent?: V; + unspecified?: V; + present: Mapper; +} + +export const getArg = ( arg: K, - args: Array, + argv: Array, + whenValue: ArgHandler, ): IEither => { - const result = args.findIndex((_arg) => _arg.startsWith(arg)); - if (result < 0) return Either.left(new Error("no argument found for " + arg)); - const [resultArg, next]: Array = [ - args[result], - args.at(result + 1), - ]; - if (resultArg && resultArg.includes("=")) { - return Either.right(resultArg.split("=")[1] as V); - } - if (typeof next === "undefined") - return Either.left(new Error("no value specified for " + arg)); - if (isArgKey(next)) - return Either.left( - new Error("next value for arg " + arg + " is another arg " + next), - ); - return Either.right(next as V); + const value = argv.filter((_argv) => isArgKey(_argv) && _argv.split("=")[0] === arg).map((_argv, i) => { + const next = _argv.includes("=") ? _argv.split("=")[1] : argv.at(i + 1); + if (next) { + if (isArgKey(next)) return whenValue.unspecified; + return whenValue.present(next); + } + return whenValue.unspecified; + }).find(x => x) ?? whenValue.absent; + if (value === undefined) { + return Either.left(new Error("no value specified for " + arg)); + } + return Either.right(value); }; -type ObjectFromList, V = string> = { - [K in T extends ReadonlyArray ? U : never]: V; +type MappedArgs< + Args extends ReadonlyArray, + Handlers extends Partial>> +> = { + [K in Args[number]]: K extends keyof Handlers + ? Handlers[K] extends ArgHandler + ? T + : string + : string; }; -export const argv = ( - args: ReadonlyArray, - defaultArgs?: Partial>, - argv = Deno.args, -) => { - return args - .map((arg) => [arg, getArg(arg, argv)] as [K, IEither]) - .map(([arg, specified]): [K, IEither] => [ - arg, - specified.fold(({ isLeft, isRight, value }): IEither => { - if (isRight) { - return Either.right(value); - } - const hasDefaultVal = isLeft && defaultArgs && arg in defaultArgs; - if (hasDefaultVal) { - return Either.right(defaultArgs[arg]!); - } - return Either.left(value); - }), - ]) - .reduce( - ( - acc: IEither>, - x: [K, IEither], - ): IEither> => { - const [arg, eitherVal] = x; - return acc.flatMap((args) => { - return eitherVal.mapRight((envValue) => ({ - ...args, - [arg]: envValue, - })); - }); - }, - Either.right({} as ObjectFromList), - ); + +export const argv = < + const Args extends ReadonlyArray, + const Handlers extends Partial>> +>( + args: Args, + handlers?: Handlers, + argv = Deno.args, +): IEither> => { + type Result = MappedArgs; + + const defaultHandler: ArgHandler = { present: (value: string) => value }; + + const processArg = (arg: Args[number]): IEither => { + const handler = handlers?.[arg] ?? defaultHandler; + return getArg(arg, argv, handler).mapRight(value => [arg, value] as const); + }; + + const argResults = args.map(processArg); + + return argResults.reduce( + (acc: IEither>, current: IEither) => { + return acc.flatMap(accValue => + current.mapRight(([key, value]) => ({ + ...accValue, + [key]: value + })) + ); + }, + Either.right({} as Partial) + ).mapRight(result => result as Result); }; -- cgit v1.2.3-70-g09d2