Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add error value getter #26

Merged
merged 9 commits into from
Apr 15, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 26 additions & 26 deletions src/option_promise.ts → src/async_option.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import {ResultPromise} from ".";
import {AsyncResult} from ".";
import type {Option, OptionMatch} from "./option";

/**
* A promise that resolves to an `Option`.
*
* This class is useful for chaining multiple asynchronous operations that return an `Option`.
*/
export class OptionPromise<T> implements PromiseLike<Option<T>> {
constructor(readonly promise: Promise<Option<T>> | PromiseLike<Option<T>>) {}
export class AsyncOption<T> implements PromiseLike<Option<T>> {
constructor(readonly promise: Promise<Option<T>> | PromiseLike<Option<T>> | AsyncOption<T>) {}

then<A, B>(
successCallback?: (res: Option<T>) => A | PromiseLike<A>,
Expand All @@ -17,7 +17,7 @@ export class OptionPromise<T> implements PromiseLike<Option<T>> {
}

catch<B>(rejectionCallback?: (reason: unknown) => B | PromiseLike<B>): PromiseLike<B> {
return this.promise.then(null, rejectionCallback);
return this.promise.then(undefined, rejectionCallback);
}

finally(callback: () => void): PromiseLike<Option<T>> {
Expand All @@ -36,38 +36,38 @@ export class OptionPromise<T> implements PromiseLike<Option<T>> {
/**
* Async version of `Option#okOr`.
*/
okOr<E>(err: E): ResultPromise<T, E> {
return new ResultPromise(this.then((option) => option.okOr(err)));
okOr<E>(err: E): AsyncResult<T, E> {
return new AsyncResult(this.then((option) => option.okOr(err)));
}

/**
* Async version of `Option#okOrElse`.
*/
okOrElse<E>(err: () => E): ResultPromise<T, E> {
return new ResultPromise(this.then((option) => option.okOrElse(err)));
okOrElse<E>(err: () => E): AsyncResult<T, E> {
return new AsyncResult(this.then((option) => option.okOrElse(err)));
}

/**
* Async version of `Option#and`.
*/
and<U>(other: OptionPromise<U>): OptionPromise<U> {
return new OptionPromise(
and<U>(other: AsyncOption<U>): AsyncOption<U> {
return new AsyncOption(
this.then((option) => other.then((otherOption) => option.and(otherOption))),
);
}

/**
* Async version of `Option#andThen`.
*/
andThen<U>(f: (value: T) => Option<U>): OptionPromise<U> {
return new OptionPromise(this.then((option) => option.andThen((value) => f(value))));
andThen<U>(f: (value: T) => Option<U>): AsyncOption<U> {
return new AsyncOption(this.then((option) => option.andThen((value) => f(value))));
}

/**
* Async version of `Option#inspect`.
*/
inspect(f: (value: T) => void): OptionPromise<T> {
return new OptionPromise(this.then((option) => option.inspect(f)));
inspect(f: (value: T) => void): AsyncOption<T> {
return new AsyncOption(this.then((option) => option.inspect(f)));
}

/**
Expand All @@ -80,22 +80,22 @@ export class OptionPromise<T> implements PromiseLike<Option<T>> {
/**
* Async version of `Option#filter`.
*/
filter(f: (value: T) => boolean): OptionPromise<T> {
return new OptionPromise(this.then((option) => option.filter(f)));
filter(f: (value: T) => boolean): AsyncOption<T> {
return new AsyncOption(this.then((option) => option.filter(f)));
}

/**
* Async version of `Option#flatten`.
*/
flatten<U>(this: OptionPromise<Option<U>>): OptionPromise<U> {
return new OptionPromise(this.then((option) => option.flatten()));
flatten<U>(this: AsyncOption<Option<U>>): AsyncOption<U> {
return new AsyncOption(this.then((option) => option.flatten()));
}

/**
* Async version of `Option#map`.
*/
map<U>(f: (value: T) => U): OptionPromise<U> {
return new OptionPromise(this.then((option) => option.map(f)));
map<U>(f: (value: T) => U): AsyncOption<U> {
return new AsyncOption(this.then((option) => option.map(f)));
}

/**
Expand All @@ -115,17 +115,17 @@ export class OptionPromise<T> implements PromiseLike<Option<T>> {
/**
* Async version of `Option#or`.
*/
or<U>(other: OptionPromise<U>): OptionPromise<T | U> {
return new OptionPromise(
or<U>(other: AsyncOption<U>): AsyncOption<T | U> {
return new AsyncOption(
this.then((thisOption) => other.then((otherOption) => thisOption.or(otherOption))),
);
}

/**
* Async version of `Option#orElse`.
*/
orElse<U>(f: () => Option<U>): OptionPromise<T | U> {
return new OptionPromise(this.then((thisOption) => thisOption.orElse(() => f())));
orElse<U>(f: () => Option<U>): AsyncOption<T | U> {
return new AsyncOption(this.then((thisOption) => thisOption.orElse(() => f())));
}

/**
Expand All @@ -152,8 +152,8 @@ export class OptionPromise<T> implements PromiseLike<Option<T>> {
/**
* Async version of `Option#xor`.
*/
xor<U>(other: OptionPromise<U>): OptionPromise<T | U> {
return new OptionPromise(
xor<U>(other: AsyncOption<U>): AsyncOption<T | U> {
return new AsyncOption(
this.then((thisOption) => other.then((otherOption) => thisOption.xor(otherOption))),
);
}
Expand Down
76 changes: 38 additions & 38 deletions src/result_promise.ts → src/async_result.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
import {OptionPromise} from "./option_promise";
import {AsyncOption} from "./async_option";
import type {Result, ResultImpl, ResultMatch} from "./result";

/**
* A promise that resolves to a `Result`.
*
* This class is useful for chaining multiple asynchronous operations that return a `Result`.
*/
export class ResultPromise<T, E> implements PromiseLike<Result<T, E>> {
export class AsyncResult<T, E> implements PromiseLike<Result<T, E>> {
constructor(
readonly promise: Promise<Result<T, E>> | PromiseLike<Result<T, E>> | ResultPromise<T, E>,
readonly promise: Promise<Result<T, E>> | PromiseLike<Result<T, E>> | AsyncResult<T, E>,
) {}

*[Symbol.iterator](): Iterator<ResultPromise<T, E>, T, any> {
*[Symbol.iterator](): Iterator<AsyncResult<T, E>, T, any> {
return yield this;
}

Expand Down Expand Up @@ -42,38 +42,38 @@ export class ResultPromise<T, E> implements PromiseLike<Result<T, E>> {
/**
* Async version of `Result#ok`.
*/
ok(): OptionPromise<T> {
return new OptionPromise(this.then((result) => result.ok()));
ok(): AsyncOption<T> {
return new AsyncOption(this.then((result) => result.ok()));
}

/**
* Async version of `Result#err`.
*/
err(): OptionPromise<E> {
return new OptionPromise(this.then((result) => result.err()));
err(): AsyncOption<E> {
return new AsyncOption(this.then((result) => result.err()));
}

/**
* Async version of `Result#and`.
*/
and<U, F>(other: ResultPromise<U, F>): ResultPromise<U, E | F> {
return new ResultPromise(
and<U, F>(other: AsyncResult<U, F>): AsyncResult<U, E | F> {
return new AsyncResult(
this.then((result) => other.then((otherResult) => result.and(otherResult))),
);
}

/**
* Async version of `Result#andThen`.
*/
andThen<U, F>(f: (value: T) => Result<U, F>): ResultPromise<U, E | F> {
return new ResultPromise(this.then((result) => result.andThen((value) => f(value))));
andThen<U, F>(f: (value: T) => Result<U, F>): AsyncResult<U, E | F> {
return new AsyncResult(this.then((result) => result.andThen((value) => f(value))));
}

/**
* Async version of `Result#andThenAsync`.
*/
andThenAsync<U, F>(f: (value: T) => Promise<Result<U, F>>): ResultPromise<U, E | F> {
return new ResultPromise(this.then((result) => result.andThenAsync((value) => f(value))));
andThenAsync<U, F>(f: (value: T) => Promise<Result<U, F>>): AsyncResult<U, E | F> {
return new AsyncResult(this.then((result) => result.andThenAsync((value) => f(value))));
}

/**
Expand All @@ -93,64 +93,64 @@ export class ResultPromise<T, E> implements PromiseLike<Result<T, E>> {
/**
* Async version of `Result#flatten`.
*/
flatten<U, F>(this: ResultPromise<ResultImpl<U, F>, E>): ResultPromise<U, E | F> {
return new ResultPromise(this.then((result) => result.flatten()));
flatten<U, F>(this: AsyncResult<ResultImpl<U, F>, E>): AsyncResult<U, E | F> {
return new AsyncResult(this.then((result) => result.flatten()));
}

/**
* Async version of `Result#inspect`.
*/
inspect(f: (value: T) => void): ResultPromise<T, E> {
return new ResultPromise(this.then((result) => result.inspect(f)));
inspect(f: (value: T) => void): AsyncResult<T, E> {
return new AsyncResult(this.then((result) => result.inspect(f)));
}

/**
* Async version of `Result#inspectAsync`.
*/
inspectAsync(f: (value: T) => Promise<void>): ResultPromise<T, E> {
return new ResultPromise(this.then((result) => result.inspectAsync(f)));
inspectAsync(f: (value: T) => Promise<void>): AsyncResult<T, E> {
return new AsyncResult(this.then((result) => result.inspectAsync(f)));
}

/**
* Async version of `Result#inspectErr`.
*/
inspectErr(f: (error: E) => void): ResultPromise<T, E> {
return new ResultPromise(this.then((result) => result.inspectErr(f)));
inspectErr(f: (error: E) => void): AsyncResult<T, E> {
return new AsyncResult(this.then((result) => result.inspectErr(f)));
}

/**
* Async version of `Result#inspectErrAsync`.
*/
inspectErrAsync(f: (error: E) => Promise<void>): ResultPromise<T, E> {
return new ResultPromise(this.then((result) => result.inspectErrAsync(f)));
inspectErrAsync(f: (error: E) => Promise<void>): AsyncResult<T, E> {
return new AsyncResult(this.then((result) => result.inspectErrAsync(f)));
}

/**
* Async version of `Result#map`.
*/
map<U>(f: (value: T) => U): ResultPromise<U, E> {
return new ResultPromise(this.then((result) => result.map(f)));
map<U>(f: (value: T) => U): AsyncResult<U, E> {
return new AsyncResult(this.then((result) => result.map(f)));
}

/**
* Async version of `Result#mapAsync`.
*/
mapAsync<U>(f: (value: T) => Promise<U>): ResultPromise<U, E> {
return new ResultPromise(this.then((result) => result.mapAsync(f)));
mapAsync<U>(f: (value: T) => Promise<U>): AsyncResult<U, E> {
return new AsyncResult(this.then((result) => result.mapAsync(f)));
}

/**
* Async version of `Result#mapErr`.
*/
mapErr<F>(f: (error: E) => F): ResultPromise<T, F> {
return new ResultPromise(this.then((result) => result.mapErr(f)));
mapErr<F>(f: (error: E) => F): AsyncResult<T, F> {
return new AsyncResult(this.then((result) => result.mapErr(f)));
}

/**
* Async version of `Result#mapErrAsync`.
*/
mapErrAsync<F>(f: (error: E) => Promise<F>): ResultPromise<T, F> {
return new ResultPromise(this.then((result) => result.mapErrAsync(f)));
mapErrAsync<F>(f: (error: E) => Promise<F>): AsyncResult<T, F> {
return new AsyncResult(this.then((result) => result.mapErrAsync(f)));
}

/**
Expand All @@ -170,24 +170,24 @@ export class ResultPromise<T, E> implements PromiseLike<Result<T, E>> {
/**
* Async version of `Result#or`.
*/
or<U, F>(other: ResultPromise<U, F>): ResultPromise<T | U, F> {
return new ResultPromise(
or<U, F>(other: AsyncResult<U, F>): AsyncResult<T | U, F> {
return new AsyncResult(
this.then((thisResult) => other.then((otherResult) => thisResult.or(otherResult))),
);
}

/**
* Async version of `Result#orElse`.
*/
orElse<U, F>(f: (error: E) => Result<U, F>): ResultPromise<T | U, F> {
return new ResultPromise(this.then((thisResult) => thisResult.orElse((error) => f(error))));
orElse<U, F>(f: (error: E) => Result<U, F>): AsyncResult<T | U, F> {
return new AsyncResult(this.then((thisResult) => thisResult.orElse((error) => f(error))));
}

/**
* Async version of `Result#orElseAsync`.
*/
orElseAsync<U, F>(f: (error: E) => Promise<Result<U, F>>): ResultPromise<T | U, F> {
return new ResultPromise(
orElseAsync<U, F>(f: (error: E) => Promise<Result<U, F>>): AsyncResult<T | U, F> {
return new AsyncResult(
this.then((thisResult) => thisResult.orElseAsync((error) => f(error))),
);
}
Expand Down
2 changes: 2 additions & 0 deletions src/common.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export const Variant = Symbol("n");
export const Value = Symbol("x");
2 changes: 1 addition & 1 deletion src/error.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,5 +47,5 @@ export function parseError(error: unknown): Error {
if (error instanceof Error) {
return error;
}
return new TypeError(`Unexpected error type: "${String(error)}"`, {cause: error});
return new TypeError(`Invalid error type: '${String(error)}'`, {cause: error});
}
Loading
Loading