import { ArgParser, ParsingResult, ParseContext, ParsingError, } from './argparser.ts'; import { OutputOf } from './from.ts'; import { PositionalArgument } from './newparser/parser.ts'; import { Type, HasType } from './type.ts'; import { ProvidesHelp, Displayed, Descriptive } from './helpdoc.ts'; import * as Result from './Result.ts'; import { string } from './types.ts'; type RestPositionalsConfig> = HasType< Decoder > & Partial; /** * Read all the positionals and decode them using the type provided. * Works best when it is the last item on the `command` construct, to be * used like the `...rest` operator in JS and TypeScript. */ function fullRestPositionals>( config: RestPositionalsConfig ): ArgParser[]> & ProvidesHelp { return { helpTopics() { const displayName = config.displayName ?? config.type.displayName ?? 'arg'; return [ { usage: `[...${displayName}]`, category: 'arguments', defaults: [], description: config.description ?? config.type.description ?? '', }, ]; }, register(_opts) {}, async parse({ nodes, visitedNodes, }: ParseContext): Promise[]>> { const positionals = nodes.filter( (node): node is PositionalArgument => node.type === 'positionalArgument' && !visitedNodes.has(node) ); const results: OutputOf[] = []; let errors: ParsingError[] = []; for (const positional of positionals) { visitedNodes.add(positional); const decoded = await Result.safeAsync( config.type.from(positional.raw) ); if (Result.isOk(decoded)) { results.push(decoded.value); } else { errors.push({ nodes: [positional], message: decoded.error.message, }); } } if (errors.length > 0) { return Result.err({ errors, }); } return Result.ok(results); }, }; } type StringType = Type; type RestPositionalsParser> = ArgParser< OutputOf[] > & ProvidesHelp; /** * Read all the positionals and decode them using the type provided. * Works best when it is the last item on the `command` construct, to be * used like the `...rest` operator in JS and TypeScript. * * @param config rest positionals argument config */ export function restPositionals>( config: HasType & Partial ): RestPositionalsParser; export function restPositionals( config?: Partial & Displayed & Descriptive> ): RestPositionalsParser; export function restPositionals( config?: Partial> & Partial ): RestPositionalsParser { return fullRestPositionals({ type: string, ...config, }); }