diff --git a/src/result.ts b/src/result.ts index 2f69b49..0408e43 100644 --- a/src/result.ts +++ b/src/result.ts @@ -180,6 +180,23 @@ class Result extends TupleConstructor { } }; + /** + * Returns the result of `transform` function if this is `Err`, otherwise it will return itself. + * + * @param transform - The function to generate the other `Result`. + * + * @returns The the result of `transform` function if this is `Err`, otherwise it will return itself. + */ + orThen = ( + transform: (res: Result) => Result + ): Result => { + if (this.isOk()) { + return this; + } else { + return transform(this); + } + }; + /** * Returns the `other` result if this is `Ok`, otherwise returns the error value of itself. * @@ -187,16 +204,33 @@ class Result extends TupleConstructor { * * @returns The `other` result if this is `Ok`, otherwise returns the error value of itself. */ - and = ( - other: Result - ): Result => { + and = ( + other: Result + ): Result => { if (this.isErr()) { - return this as unknown as Result; + return this as unknown as Result; } else { return other; } }; + /** + * Returns the result of the `transform` function if this is `Ok`, otherwise returns the error value of itself. + * + * @param transform - The function to generate the other `Result`. + * + * @returns The result of the `transform` function if this is `Ok`, otherwise returns the error value of itself. + */ + andThen = ( + transform: (res: Result) => Result + ): Result => { + if (this.isErr()) { + return this as unknown as Result; + } else { + return transform(this); + } + }; + /** * It will match the result with the given `Matcher`s and return the result. * diff --git a/tests/result.spec.ts b/tests/result.spec.ts index 923e475..ffad02d 100644 --- a/tests/result.spec.ts +++ b/tests/result.spec.ts @@ -73,6 +73,30 @@ describe("Result 'or' function Tests", () => { }); }); +describe("Result 'orThen' function Tests", () => { + const firstOk = Ok("FIRST_OK"); + const secondOk = Ok("SECOND_OK"); + + const firstErr = Err("FIRST_ERR"); + const secondErr = Err("SECOND_ERR"); + + test("should return first Result if first Result is Ok", () => { + expect(firstOk.orThen((_) => secondOk)).toBe(firstOk); + }); + + test("should return second Result if first Result is Err", () => { + expect(firstErr.orThen((_) => secondOk)).toBe(secondOk); + }); + + test("should return second Err Result if both Results are Err", () => { + expect(firstErr.orThen((_) => secondErr).isErr()).toBe(true); + }); + + test("should return first Ok Result if both Results are Ok", () => { + expect(firstOk.orThen((_) => secondOk).isOk()).toBe(true); + }); +}); + describe("Result 'and' function Tests", () => { const firstOk = Ok("FIRST_OK"); const secondOk = Ok("SECOND_OK"); @@ -97,6 +121,30 @@ describe("Result 'and' function Tests", () => { }); }); +describe("Result 'andThen' function Tests", () => { + const firstOk = Ok("FIRST_OK"); + const secondOk = Ok("SECOND_OK"); + + const firstErr = Err("FIRST_ERR"); + const secondErr = Err("SECOND_ERR"); + + test("should return second result if first one is Ok", () => { + expect(firstOk.andThen((_) => secondErr)).toBe(secondErr); + }); + + test("should return first result if it is Err", () => { + expect(firstErr.andThen((_) => secondOk)).toBe(firstErr); + }); + + test("should return first result if both are Err", () => { + expect(firstErr.andThen((_) => secondErr)).toBe(firstErr); + }); + + test("should return second result if both are Ok", () => { + expect(firstOk.andThen((_) => secondOk)).toBe(secondOk); + }); +}); + describe("Err Result Tests", () => { test("should return a Result reporting isErr status", () => { expect(Err(undefined).isErr()).toBe(true);