diff --git a/lib/util/result.spec.ts b/lib/util/result.spec.ts index a035fce181521d1caeab891e3d76216291bfaee6..4a22eec2ee93030906e39a91372b25f46a68db9d 100644 --- a/lib/util/result.spec.ts +++ b/lib/util/result.spec.ts @@ -31,18 +31,29 @@ describe('util/result', () => { }); describe('Wrapping', () => { - it('wraps callback', () => { + it('wraps callback returning value', () => { const res = Result.wrap(() => 42); expect(res).toEqual(Result.ok(42)); }); - it('handles callback error', () => { + it('handles throw in callback', () => { const res = Result.wrap(() => { throw 'oops'; }); expect(res).toEqual(Result.err('oops')); }); + it('wraps callback returning promise', () => { + const res = Result.wrap(() => Promise.resolve(42)); + expect(res).toEqual(AsyncResult.ok(42)); + }); + + it('wraps callback returning failed promise', () => { + const err = new Error('unknown'); + const res = Result.wrap(() => Promise.reject(err)); + expect(res).toEqual(AsyncResult.err(err)); + }); + it('wraps nullable callback', () => { const res: Result<number, 'oops'> = Result.wrapNullable( (): number | null => 42, diff --git a/lib/util/result.ts b/lib/util/result.ts index af699f33eaa448c50992d57ffdf2d9a0fd50a3f6..86f48acdf2620b4aeb5a66c37b0e855cb962e08b 100644 --- a/lib/util/result.ts +++ b/lib/util/result.ts @@ -142,6 +142,9 @@ export class Result<T extends Val, E extends Val = Error> { static wrap<T extends Val, E extends Val = Error>( callback: () => RawValue<T>, ): Result<T, E>; + static wrap<T extends Val, E extends Val = Error>( + callback: () => Promise<RawValue<T>>, + ): AsyncResult<T, E>; static wrap<T extends Val, E extends Val = Error, EE extends Val = never>( promise: Promise<Result<T, EE>>, ): AsyncResult<T, E | EE>; @@ -157,6 +160,7 @@ export class Result<T extends Val, E extends Val = Error> { input: | SafeParseReturnType<Input, T> | (() => RawValue<T>) + | (() => Promise<RawValue<T>>) | Promise<Result<T, EE>> | Promise<RawValue<T>>, ): Result<T, ZodError<Input>> | Result<T, E | EE> | AsyncResult<T, E | EE> { @@ -170,6 +174,11 @@ export class Result<T extends Val, E extends Val = Error> { try { const result = input(); + + if (result instanceof Promise) { + return AsyncResult.wrap(result); + } + return Result.ok(result); } catch (error) { return Result.err(error);