From b264c3eaf18f498e2d52641767d859a108b0c211 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?A=2E=20Rom=C3=A1n?= Date: Fri, 5 Aug 2022 20:47:56 +0200 Subject: [PATCH] refactor: better Args Result types (#501) * refactor: better Args Result types * Update src/lib/structures/Argument.ts Co-authored-by: Vlad Frangu Co-authored-by: Vlad Frangu --- src/lib/parsers/Args.ts | 40 +++++++++++++++++++--------------- src/lib/structures/Argument.ts | 23 ++++++++++--------- 2 files changed, 35 insertions(+), 28 deletions(-) diff --git a/src/lib/parsers/Args.ts b/src/lib/parsers/Args.ts index d00f2888a..83bd30044 100644 --- a/src/lib/parsers/Args.ts +++ b/src/lib/parsers/Args.ts @@ -1,6 +1,8 @@ import type { ChannelTypes, GuildBasedChannelTypes } from '@sapphire/discord.js-utilities'; +import type { ArgumentStream, Parameter } from '@sapphire/lexure'; import { container } from '@sapphire/pieces'; import { Option, Result } from '@sapphire/result'; +import type { Awaitable } from '@sapphire/utilities'; import type { CategoryChannel, DMChannel, @@ -14,7 +16,6 @@ import type { User, VoiceChannel } from 'discord.js'; -import type { ArgumentStream, Parameter } from '@sapphire/lexure'; import type { URL } from 'url'; import { ArgumentError } from '../errors/ArgumentError'; import { Identifiers } from '../errors/Identifiers'; @@ -87,7 +88,7 @@ export class Args { * // Sends "The result is: 25" * ``` */ - public async pickResult(type: IArgument, options?: ArgOptions): Promise>; + public async pickResult(type: IArgument, options?: ArgOptions): Promise>; /** * Retrieves the next parameter and parses it. Advances index on success. * @param type The type of the argument. @@ -104,8 +105,8 @@ export class Args { * // Sends "The result is: 3" * ``` */ - public async pickResult(type: K, options?: ArgOptions): Promise>; - public async pickResult(type: K, options: ArgOptions = {}): Promise> { + public async pickResult(type: K, options?: ArgOptions): Promise>; + public async pickResult(type: K, options: ArgOptions = {}): Promise> { const argument = this.resolveArgument(type); if (!argument) return this.unavailableArgument(type); @@ -123,7 +124,7 @@ export class Args { return this.missingArguments(); } - return result as Result; + return result as ResultType; } /** @@ -176,7 +177,7 @@ export class Args { * // Sends "The reversed value is... !dlrow olleH" * ``` */ - public async restResult(type: IArgument, options?: ArgOptions): Promise>; + public async restResult(type: IArgument, options?: ArgOptions): Promise>; /** * Retrieves all the following arguments. * @param type The type of the argument. @@ -193,8 +194,8 @@ export class Args { * // Sends "The repeated value is... Hello World!Hello World!" * ``` */ - public async restResult(type: K, options?: ArgOptions): Promise>; - public async restResult(type: keyof ArgType | IArgument, options: ArgOptions = {}): Promise> { + public async restResult(type: K, options?: ArgOptions): Promise>; + public async restResult(type: keyof ArgType | IArgument, options: ArgOptions = {}): Promise> { const argument = this.resolveArgument(type); if (!argument) return this.unavailableArgument(type); if (this.parser.finished) return this.missingArguments(); @@ -261,7 +262,7 @@ export class Args { * // Sends "You have written 2 word(s): olleH !dlroW" * ``` */ - public async repeatResult(type: IArgument, options?: RepeatArgOptions): Promise>; + public async repeatResult(type: IArgument, options?: RepeatArgOptions): Promise>; /** * Retrieves all the following arguments. * @param type The type of the argument. @@ -275,8 +276,8 @@ export class Args { * // Sends "You have written 2 word(s): Hello World!" * ``` */ - public async repeatResult(type: K, options?: RepeatArgOptions): Promise>; - public async repeatResult(type: K, options: RepeatArgOptions = {}): Promise> { + public async repeatResult(type: K, options?: RepeatArgOptions): Promise>; + public async repeatResult(type: K, options: RepeatArgOptions = {}): Promise> { const argument = this.resolveArgument(type); if (!argument) return this.unavailableArgument(type); if (this.parser.finished) return this.missingArguments(); @@ -298,7 +299,7 @@ export class Args { if (error === null) break; if (output.length === 0) { - return result as Result.Err; + return result as Result.Err>; } break; @@ -360,7 +361,7 @@ export class Args { * if (isOk(firstWord)) await message.channel.send(firstWord.value.toUpperCase()); // HELLO * ``` */ - public async peekResult(type: () => Argument.Result): Promise>; + public async peekResult(type: () => Argument.Result): Promise>; /** * Peeks the following parameter(s) without advancing the parser's state. * Passing a function as a parameter allows for returning {@link Args.pickResult}, {@link Args.repeatResult}, @@ -379,7 +380,7 @@ export class Args { * if (isOk(firstWord)) await message.channel.send(firstWord.value.toUpperCase()); // SAPPHIRE * ``` */ - public async peekResult(type: IArgument, options?: ArgOptions): Promise>; + public async peekResult(type: IArgument, options?: ArgOptions): Promise>; /** * Peeks the following parameter(s) without advancing the parser's state. * Passing a function as a parameter allows for returning {@link Args.pickResult}, {@link Args.repeatResult}, @@ -399,14 +400,14 @@ export class Args { * ``` */ public async peekResult( - type: (() => Argument.Result) | K, + type: (() => Awaitable>) | K, options?: ArgOptions - ): Promise>; + ): Promise>; public async peekResult( - type: (() => Argument.Result) | K, + type: (() => Awaitable>) | K, options: ArgOptions = {} - ): Promise> { + ): Promise> { this.save(); const result = typeof type === 'function' ? await type() : await this.pickResult(type, options); this.restore(); @@ -732,3 +733,6 @@ export interface ArgsNextCallback { */ (value: string): Option; } + +export type ResultType = Result>; +export type ArrayResultType = Result>; diff --git a/src/lib/structures/Argument.ts b/src/lib/structures/Argument.ts index 5855c9daf..a3aa04c74 100644 --- a/src/lib/structures/Argument.ts +++ b/src/lib/structures/Argument.ts @@ -3,19 +3,23 @@ import type { Result } from '@sapphire/result'; import type { Awaitable } from '@sapphire/utilities'; import type { Message } from 'discord.js'; import type { ArgumentError } from '../errors/ArgumentError'; -import type { UserError } from '../errors/UserError'; import { Args } from '../parsers/Args'; import type { MessageCommand } from './Command'; /** * Defines a synchronous result of an {@link Argument}, check {@link Argument.AsyncResult} for the asynchronous version. */ -export type ArgumentResult = Awaitable>; +export type ArgumentResult = Result>; + +/** + * Defines a synchronous or asynchronous result of an {@link Argument}, check {@link Argument.AsyncResult} for the asynchronous version. + */ +export type AwaitableArgumentResult = Awaitable>; /** * Defines an asynchronous result of an {@link Argument}, check {@link Argument.Result} for the synchronous version. */ -export type AsyncArgumentResult = Promise>; +export type AsyncArgumentResult = Promise>; export interface IArgument { /** @@ -28,7 +32,7 @@ export interface IArgument { * @param parameter The string parameter to parse. * @param context The context for the method call, contains the message, command, and other options. */ - run(parameter: string, context: Argument.Context): Argument.Result; + run(parameter: string, context: Argument.Context): Argument.AwaitableResult; } /** @@ -88,23 +92,21 @@ export interface IArgument { * ``` */ export abstract class Argument extends AliasPiece implements IArgument { - public abstract run(parameter: string, context: Argument.Context): Argument.Result; + public abstract run(parameter: string, context: Argument.Context): Argument.AwaitableResult; /** * Wraps a value into a successful value. * @param value The value to wrap. */ - public ok(value: T): Result { + public ok(value: T): Argument.Result { return Args.ok(value); } /** * Constructs an {@link Err} result containing an {@link ArgumentError} with a custom type. - * @param parameter The parameter that triggered the argument. - * @param type The identifier for the error. - * @param message The description message for the rejection. + * @param options The options to pass to the ArgumentError. */ - public error(options: Omit, 'argument'>): Result { + public error(options: Omit, 'argument'>): Argument.Result { return Args.error({ argument: this, identifier: this.name, ...options }); } } @@ -126,5 +128,6 @@ export namespace Argument { export type Options = ArgumentOptions; export type Context = ArgumentContext; export type Result = ArgumentResult; + export type AwaitableResult = AwaitableArgumentResult; export type AsyncResult = AsyncArgumentResult; }