Skip to content

Commit

Permalink
feat: add orThen and andThen functions to Result
Browse files Browse the repository at this point in the history
  • Loading branch information
rzvxa committed Dec 28, 2023
1 parent 121f716 commit f0dc02c
Show file tree
Hide file tree
Showing 2 changed files with 86 additions and 4 deletions.
42 changes: 38 additions & 4 deletions src/result.ts
Original file line number Diff line number Diff line change
Expand Up @@ -180,23 +180,57 @@ class Result<TResult, TError> extends TupleConstructor<TResult, TError> {
}
};

/**
* 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<TResult, TError>) => Result<TResult, TError>
): Result<TResult, TError> => {
if (this.isOk()) {
return this;
} else {
return transform(this);
}
};

/**
* Returns the `other` result if this is `Ok`, otherwise returns the error value of itself.
*
* @param other - The other `Result`.
*
* @returns The `other` result if this is `Ok`, otherwise returns the error value of itself.
*/
and = <TResultOther>(
other: Result<TResultOther, TError>
): Result<TResultOther, TError> => {
and = <TNewResult>(
other: Result<TNewResult, TError>
): Result<TNewResult, TError> => {
if (this.isErr()) {
return this as unknown as Result<TResultOther, TError>;
return this as unknown as Result<TNewResult, TError>;
} 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 = <TNewResult>(
transform: (res: Result<TResult, TError>) => Result<TNewResult, TError>
): Result<TNewResult, TError> => {
if (this.isErr()) {
return this as unknown as Result<TNewResult, TError>;
} else {
return transform(this);
}
};

/**
* It will match the result with the given `Matcher`s and return the result.
*
Expand Down
48 changes: 48 additions & 0 deletions tests/result.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,30 @@ describe("Result 'or' function Tests", () => {
});
});

describe("Result 'orThen' function Tests", () => {
const firstOk = Ok<unknown, unknown>("FIRST_OK");
const secondOk = Ok<unknown, unknown>("SECOND_OK");

const firstErr = Err<unknown, unknown>("FIRST_ERR");
const secondErr = Err<unknown, unknown>("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<unknown, unknown>("FIRST_OK");
const secondOk = Ok<unknown, unknown>("SECOND_OK");
Expand All @@ -97,6 +121,30 @@ describe("Result 'and' function Tests", () => {
});
});

describe("Result 'andThen' function Tests", () => {
const firstOk = Ok<unknown, unknown>("FIRST_OK");
const secondOk = Ok<unknown, unknown>("SECOND_OK");

const firstErr = Err<unknown, unknown>("FIRST_ERR");
const secondErr = Err<unknown, unknown>("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);
Expand Down

0 comments on commit f0dc02c

Please sign in to comment.