614 lines
20 KiB
JavaScript
614 lines
20 KiB
JavaScript
|
/** [[include:doc/result.md]] */
|
||
|
/** (keep typedoc from getting confused by the import) */
|
||
|
import * as Maybe from './maybe';
|
||
|
import Unit from './unit';
|
||
|
import { _Brand, curry1, isVoid } from './utils';
|
||
|
// So that it doesn't appear unused but can be exported.
|
||
|
_Brand; // tslint:disable-line:no-unused-expression
|
||
|
/**
|
||
|
Discriminant for `Ok` and `Err` variants of `Result` type.
|
||
|
|
||
|
You can use the discriminant via the `variant` property of `Result` instances
|
||
|
if you need to match explicitly on it.
|
||
|
*/
|
||
|
export var Variant;
|
||
|
(function (Variant) {
|
||
|
Variant["Ok"] = "Ok";
|
||
|
Variant["Err"] = "Err";
|
||
|
})(Variant || (Variant = {}));
|
||
|
/**
|
||
|
An `Ok` instance is the *successful* variant instance of the
|
||
|
[`Result`](../modules/_result_.html#result) type, representing a successful
|
||
|
outcome from an operation which may fail. For a full discussion, see [the
|
||
|
module docs](../modules/_result_.html).
|
||
|
|
||
|
@typeparam T The type wrapped in this `Ok` variant of `Result`.
|
||
|
@typeparam E The type which would be wrapped in an `Err` variant of `Result`.
|
||
|
*/
|
||
|
export class Ok {
|
||
|
/**
|
||
|
Create an instance of `Result.Ok` with `new`.
|
||
|
|
||
|
Note: While you *may* create the `Result` type via normal
|
||
|
JavaScript class construction, it is not recommended for the functional
|
||
|
style for which the library is intended. Instead, use [`Result.ok`].
|
||
|
|
||
|
[`Result.ok`]: ../modules/_result_.html#ok
|
||
|
|
||
|
```ts
|
||
|
// Avoid:
|
||
|
const aString = new Result.Ok('characters');
|
||
|
|
||
|
// Prefer:
|
||
|
const aString = Result.ok('characters);
|
||
|
```
|
||
|
|
||
|
Note that you may explicitly pass `Unit` to the `Ok` constructor to create
|
||
|
a `Result<Unit, E>`. However, you may *not* call the `Ok` constructor with
|
||
|
`null` or `undefined` to get that result (the type system won't allow you to
|
||
|
construct it that way). Instead, for convenience, you can simply call
|
||
|
`Result.ok()`, which will construct the type correctly.
|
||
|
|
||
|
@param value
|
||
|
The value to wrap in a `Result.Ok`.
|
||
|
|
||
|
Note: `null` and `undefined` are allowed by the type signature so that the
|
||
|
constructor may `throw` on those rather than constructing a type like
|
||
|
`Result<undefined>`.
|
||
|
|
||
|
@throws If you pass `null`.
|
||
|
*/
|
||
|
constructor(value) {
|
||
|
/** `Ok` is always [`Variant.Ok`](../enums/_result_.variant#ok). */
|
||
|
this.variant = Variant.Ok;
|
||
|
if (isVoid(value)) {
|
||
|
throw new Error('Tried to construct `Ok` with `null` or `undefined`. Maybe you want `Maybe.Nothing`?');
|
||
|
}
|
||
|
this.value = value;
|
||
|
}
|
||
|
/**
|
||
|
Unwrap the contained value. A convenience method for functional idioms.
|
||
|
|
||
|
A common scenario where you might want to use this is in a pipeline of
|
||
|
functions:
|
||
|
|
||
|
```ts
|
||
|
import Result, { Ok } from 'true-myth/result';
|
||
|
|
||
|
function getLengths(results: Array<Result<string, string>>): Array<number> {
|
||
|
return results
|
||
|
.filter(Result.isOk)
|
||
|
.map(Ok.unwrap)
|
||
|
.map(s => s.length);
|
||
|
}
|
||
|
```
|
||
|
*/
|
||
|
static unwrap(theOk) {
|
||
|
return theOk.value;
|
||
|
}
|
||
|
/** Method variant for [`Result.isOk`](../modules/_result_.html#isok) */
|
||
|
isOk() {
|
||
|
return true;
|
||
|
}
|
||
|
/** Method variant for [`Result.isErr`](../modules/_result_.html#iserr) */
|
||
|
isErr() {
|
||
|
return false;
|
||
|
}
|
||
|
/** Method variant for [`Result.map`](../modules/_result_.html#map) */
|
||
|
map(mapFn) {
|
||
|
return map(mapFn, this);
|
||
|
}
|
||
|
/** Method variant for [`Result.mapOr`](../modules/_result_.html#mapor) */
|
||
|
mapOr(orU, mapFn) {
|
||
|
return mapOr(orU, mapFn, this);
|
||
|
}
|
||
|
/** Method variant for [`Result.mapOrElse`](../modules/_result_.html#maporelse) */
|
||
|
mapOrElse(orElseFn, mapFn) {
|
||
|
return mapOrElse(orElseFn, mapFn, this);
|
||
|
}
|
||
|
/** Method variant for [`Result.match`](../modules/_result_.html#match) */
|
||
|
match(matcher) {
|
||
|
return match(matcher, this);
|
||
|
}
|
||
|
/** Method variant for [`Result.mapErr`](../modules/_result_.html#maperr) */
|
||
|
mapErr(mapErrFn) {
|
||
|
return mapErr(mapErrFn, this);
|
||
|
}
|
||
|
/** Method variant for [`Result.or`](../modules/_result_.html#or) */
|
||
|
or(orResult) {
|
||
|
return or(orResult, this);
|
||
|
}
|
||
|
/** Method variant for [`Result.orElse`](../modules/_result_.html#orelse) */
|
||
|
orElse(orElseFn) {
|
||
|
return orElse(orElseFn, this);
|
||
|
}
|
||
|
/** Method variant for [`Result.and`](../modules/_result_.html#and) */
|
||
|
and(mAnd) {
|
||
|
return and(mAnd, this);
|
||
|
}
|
||
|
/** Method variant for [`Result.andThen`](../modules/_result_.html#andthen) */
|
||
|
andThen(andThenFn) {
|
||
|
return andThen(andThenFn, this);
|
||
|
}
|
||
|
/** Method variant for [`Result.chain`](../modules/_result_.html#chain) */
|
||
|
chain(chainFn) {
|
||
|
return chain(chainFn, this);
|
||
|
}
|
||
|
/** Method variant for [`Result.flatMap`](../modules/_result_.html#flatmap) */
|
||
|
flatMap(flatMapFn) {
|
||
|
return flatMap(flatMapFn, this);
|
||
|
}
|
||
|
/** Method variant for [`Result.unwrap`](../modules/_result_.html#unwrap) */
|
||
|
unsafelyUnwrap() {
|
||
|
return this.value;
|
||
|
}
|
||
|
/** Method variant for [`Result.unwrapErr`](../modules/_result_.html#unwraperr) */
|
||
|
unsafelyUnwrapErr() {
|
||
|
throw new Error('Tried to `unsafelyUnwrapErr` an `Ok`');
|
||
|
}
|
||
|
/** Method variant for [`Result.unwrapOr`](../modules/_result_.html#unwrapor) */
|
||
|
unwrapOr(defaultValue) {
|
||
|
return unwrapOr(defaultValue, this);
|
||
|
}
|
||
|
/** Method variant for [`Result.unwrapOrElse`](../modules/_result_.html#unwrapOrElse) */
|
||
|
unwrapOrElse(elseFn) {
|
||
|
return unwrapOrElse(elseFn, this);
|
||
|
}
|
||
|
/** Method variant for [`Result.toMaybe`](../modules/_result_.html#tomaybe) */
|
||
|
toMaybe() {
|
||
|
return toMaybe(this);
|
||
|
}
|
||
|
/** Method variant for [`Result.toString`](../modules/_result_.html#tostring) */
|
||
|
toString() {
|
||
|
return toString(this);
|
||
|
}
|
||
|
/** Method variant for [`Result.toJSON`](../modules/_result_.html#toJSON) */
|
||
|
toJSON() {
|
||
|
return toJSON(this);
|
||
|
}
|
||
|
/** Method variant for [`Result.equals`](../modules/_result_.html#equals) */
|
||
|
equals(comparison) {
|
||
|
return equals(comparison, this);
|
||
|
}
|
||
|
/** Method variant for [`Result.ap`](../modules/_result_.html#ap) */
|
||
|
ap(r) {
|
||
|
return ap(this, r);
|
||
|
}
|
||
|
}
|
||
|
/**
|
||
|
An `Err` instance is the *failure* variant instance of the
|
||
|
[`Result`](../modules/_result_.html#result) type, representing a failure
|
||
|
outcome from an operation which may fail. For a full discussion, see [the
|
||
|
module docs](../modules/_result_.html).
|
||
|
|
||
|
@typeparam T The type which would be wrapped in an `Ok` variant of `Result`.
|
||
|
@typeparam E The type wrapped in this `Err` variant of `Result`.
|
||
|
*/
|
||
|
export class Err {
|
||
|
/**
|
||
|
Create an instance of `Result.Err` with `new`.
|
||
|
|
||
|
Note: While you *may* create the `Result` type via normal
|
||
|
JavaScript class construction, it is not recommended for the functional
|
||
|
style for which the library is intended. Instead, use [`Result.err`].
|
||
|
|
||
|
[`Result.err`]: ../modules/_result_.html#err
|
||
|
|
||
|
```ts
|
||
|
// Avoid:
|
||
|
const anErr = new Result.Err('alas, failure');
|
||
|
|
||
|
// Prefer:
|
||
|
const anErr = Result.err('alas, failure');
|
||
|
```
|
||
|
|
||
|
Note that you may explicitly pass `Unit` to the `Err` constructor to create
|
||
|
a `Result<T, Unit>`. However, you may *not* call the `Err` constructor with
|
||
|
`null` or `undefined` to get that result (the type system won't allow you to
|
||
|
construct it that way). Instead, for convenience, you can simply call
|
||
|
`Result.err()`, which will construct the type correctly.
|
||
|
|
||
|
@param error
|
||
|
The value to wrap in a `Result.Err`.
|
||
|
|
||
|
`Note: null` and `undefined` are allowed by the type signature so that the
|
||
|
constructor may `throw` on those rather than constructing a type like
|
||
|
`Result<number, undefined>`.
|
||
|
|
||
|
@throws If you pass `null` or `undefined`.
|
||
|
*/
|
||
|
constructor(error) {
|
||
|
/** `Err` is always [`Variant.Err`](../enums/_result_.variant#err). */
|
||
|
this.variant = Variant.Err;
|
||
|
if (isVoid(error)) {
|
||
|
throw new Error('Tried to construct `Err` with `null` or `undefined`. Maybe you want `Maybe.Nothing`?');
|
||
|
}
|
||
|
this.error = error;
|
||
|
}
|
||
|
/**
|
||
|
Unwrap the contained error . A convenience method for functional idioms.
|
||
|
|
||
|
A common scenario where you might want to use this is in a pipeline of
|
||
|
functions:
|
||
|
|
||
|
```ts
|
||
|
import Result, { Ok } from 'true-myth/result';
|
||
|
|
||
|
function getMessages(results: Array<Result<string, Error>>): Array<number> {
|
||
|
return maybeStrings
|
||
|
.filter(Result.isErr)
|
||
|
.map(Err.unwrapErr)
|
||
|
.map(e => e.message);
|
||
|
}
|
||
|
```
|
||
|
*/
|
||
|
static unwrapErr(theErr) {
|
||
|
return theErr.error;
|
||
|
}
|
||
|
/** Method variant for [`Result.isOk`](../modules/_result_.html#isok) */
|
||
|
isOk() {
|
||
|
return false;
|
||
|
}
|
||
|
/** Method variant for [`Result.isErr`](../modules/_result_.html#iserr) */
|
||
|
isErr() {
|
||
|
return true;
|
||
|
}
|
||
|
/** Method variant for [`Result.map`](../modules/_result_.html#map) */
|
||
|
map(mapFn) {
|
||
|
return map(mapFn, this);
|
||
|
}
|
||
|
/** Method variant for [`Result.mapOr`](../modules/_result_.html#mapor) */
|
||
|
mapOr(orU, mapFn) {
|
||
|
return mapOr(orU, mapFn, this);
|
||
|
}
|
||
|
/** Method variant for [`Result.mapOrElse`](../modules/_result_.html#maporelse) */
|
||
|
mapOrElse(orElseFn, mapFn) {
|
||
|
return mapOrElse(orElseFn, mapFn, this);
|
||
|
}
|
||
|
/** Method variant for [`Result.match`](../modules/_result_.html#match) */
|
||
|
match(matchObj) {
|
||
|
return match(matchObj, this);
|
||
|
}
|
||
|
/** Method variant for [`Result.mapErr`](../modules/_result_.html#maperr) */
|
||
|
mapErr(mapErrFn) {
|
||
|
return mapErr(mapErrFn, this);
|
||
|
}
|
||
|
/** Method variant for [`Result.or`](../modules/_result_.html#or) */
|
||
|
or(orResult) {
|
||
|
return or(orResult, this);
|
||
|
}
|
||
|
/** Method variant for [`Result.orElse`](../modules/_result_.html#orelse) */
|
||
|
orElse(orElseFn) {
|
||
|
return orElse(orElseFn, this);
|
||
|
}
|
||
|
/** Method variant for [`Result.and`](../modules/_result_.html#and) */
|
||
|
and(mAnd) {
|
||
|
return and(mAnd, this);
|
||
|
}
|
||
|
/** Method variant for [`Result.andThen`](../modules/_result_.html#andthen) */
|
||
|
andThen(andThenFn) {
|
||
|
return andThen(andThenFn, this);
|
||
|
}
|
||
|
/** Method variant for [`Result.chain`](../modules/_result_.html#chain) */
|
||
|
chain(chainFn) {
|
||
|
return this.andThen(chainFn);
|
||
|
}
|
||
|
/** Method variant for [`Result.flatMap`](../modules/_result_.html#flatmap) */
|
||
|
flatMap(flatMapFn) {
|
||
|
return this.andThen(flatMapFn);
|
||
|
}
|
||
|
/** Method variant for [`Result.unsafelyUnwrap`](../modules/_result_.html#unsafelyunwrap) */
|
||
|
unsafelyUnwrap() {
|
||
|
throw new Error('Tried to `unsafelyUnwrap an Err`');
|
||
|
}
|
||
|
/** Method variant for [`Result.unsafelyUnwrapErr`](../modules/_result_.html#unsafelyunwraperr) */
|
||
|
unsafelyUnwrapErr() {
|
||
|
return this.error;
|
||
|
}
|
||
|
/** Method variant for [`Result.unwrapOr`](../modules/_result_.html#unwrapor) */
|
||
|
unwrapOr(defaultValue) {
|
||
|
return unwrapOr(defaultValue, this);
|
||
|
}
|
||
|
/** Method variant for [`Result.unwrapOrElse`](../modules/_result_.html#unwraporelse) */
|
||
|
unwrapOrElse(elseFn) {
|
||
|
return unwrapOrElse(elseFn, this);
|
||
|
}
|
||
|
/** Method variant for [`Result.toMaybe`](../modules/_result_.html#tomaybe) */
|
||
|
toMaybe() {
|
||
|
return toMaybe(this);
|
||
|
}
|
||
|
/** Method variant for [`Result.toString`](../modules/_result_.html#tostring) */
|
||
|
toString() {
|
||
|
return toString(this);
|
||
|
}
|
||
|
/** Method variant for [`Result.toJSON`](../modules/_result_.html#toJSON) */
|
||
|
toJSON() {
|
||
|
return toJSON(this);
|
||
|
}
|
||
|
/** Method variant for [`Result.equals`](../modules/_result_.html#equals) */
|
||
|
equals(comparison) {
|
||
|
return equals(comparison, this);
|
||
|
}
|
||
|
/** Method variant for [`Result.ap`](../modules/_result_.html#ap) */
|
||
|
ap(r) {
|
||
|
return ap(this, r);
|
||
|
}
|
||
|
}
|
||
|
/**
|
||
|
Is this `Result` an `Ok` instance?
|
||
|
|
||
|
In TypeScript, narrows the type from `Result<T, E>` to `Ok<T, E>`.
|
||
|
*/
|
||
|
export function isOk(result) {
|
||
|
return result.variant === Variant.Ok;
|
||
|
}
|
||
|
/**
|
||
|
Is this `Result` an `Err` instance?
|
||
|
|
||
|
In TypeScript, narrows the type from `Result<T, E>` to `Err<T, E>`.
|
||
|
*/
|
||
|
export function isErr(result) {
|
||
|
return result.variant === Variant.Err;
|
||
|
}
|
||
|
export function ok(value) {
|
||
|
return value === undefined ? new Ok(Unit) : new Ok(value);
|
||
|
}
|
||
|
/** `Result.of` is an alias for `Result.ok`. */
|
||
|
export const of = ok;
|
||
|
export function err(error) {
|
||
|
return isVoid(error) ? new Err(Unit) : new Err(error);
|
||
|
}
|
||
|
export function tryOr(error, callback) {
|
||
|
const op = (cb) => {
|
||
|
try {
|
||
|
return Result.ok(cb());
|
||
|
}
|
||
|
catch (_a) {
|
||
|
return Result.err(error);
|
||
|
}
|
||
|
};
|
||
|
return curry1(op, callback);
|
||
|
}
|
||
|
export function tryOrElse(onError, callback) {
|
||
|
const op = (cb) => {
|
||
|
try {
|
||
|
return Result.ok(cb());
|
||
|
}
|
||
|
catch (e) {
|
||
|
return Result.err(onError(e));
|
||
|
}
|
||
|
};
|
||
|
return curry1(op, callback);
|
||
|
}
|
||
|
export function map(mapFn, result) {
|
||
|
const op = (r) => (isOk(r) ? ok(mapFn(r.value)) : r);
|
||
|
return curry1(op, result);
|
||
|
}
|
||
|
export function mapOr(orU, mapFn, result) {
|
||
|
function fullOp(fn, r) {
|
||
|
return isOk(r) ? fn(r.value) : orU;
|
||
|
}
|
||
|
function partialOp(fn, curriedResult) {
|
||
|
return curriedResult !== undefined
|
||
|
? fullOp(fn, curriedResult)
|
||
|
: (extraCurriedResult) => fullOp(fn, extraCurriedResult);
|
||
|
}
|
||
|
return mapFn === undefined
|
||
|
? partialOp
|
||
|
: result === undefined
|
||
|
? partialOp(mapFn)
|
||
|
: partialOp(mapFn, result);
|
||
|
}
|
||
|
export function mapOrElse(orElseFn, mapFn, result) {
|
||
|
function fullOp(fn, r) {
|
||
|
return isOk(r) ? fn(r.value) : orElseFn(r.error);
|
||
|
}
|
||
|
function partialOp(fn, curriedResult) {
|
||
|
return curriedResult !== undefined
|
||
|
? fullOp(fn, curriedResult)
|
||
|
: (extraCurriedResult) => fullOp(fn, extraCurriedResult);
|
||
|
}
|
||
|
return mapFn === undefined
|
||
|
? partialOp
|
||
|
: result === undefined
|
||
|
? partialOp(mapFn)
|
||
|
: partialOp(mapFn, result);
|
||
|
}
|
||
|
export function mapErr(mapErrFn, result) {
|
||
|
const op = (r) => (isOk(r) ? r : err(mapErrFn(r.error)));
|
||
|
return curry1(op, result);
|
||
|
}
|
||
|
export function and(andResult, result) {
|
||
|
const op = (r) => (isOk(r) ? andResult : r);
|
||
|
return curry1(op, result);
|
||
|
}
|
||
|
export function andThen(thenFn, result) {
|
||
|
const op = (r) => (isOk(r) ? thenFn(r.value) : r);
|
||
|
return curry1(op, result);
|
||
|
}
|
||
|
/** Alias for [`andThen`](#andthen). */
|
||
|
export const chain = andThen;
|
||
|
/** Alias for [`andThen`](#andthen). */
|
||
|
export const flatMap = andThen;
|
||
|
export function or(defaultResult, result) {
|
||
|
const op = (r) => (isOk(r) ? r : defaultResult);
|
||
|
return curry1(op, result);
|
||
|
}
|
||
|
export function orElse(elseFn, result) {
|
||
|
const op = (r) => (isOk(r) ? r : elseFn(r.unsafelyUnwrapErr()));
|
||
|
return curry1(op, result);
|
||
|
}
|
||
|
/**
|
||
|
Get the value out of the `Result`.
|
||
|
|
||
|
Returns the content of an `Ok`, but **throws if the `Result` is `Err`.**
|
||
|
Prefer to use [`unwrapOr`](#unwrapor) or [`unwrapOrElse`](#unwraporelse).
|
||
|
|
||
|
@throws If the `Result` instance is `Nothing`.
|
||
|
*/
|
||
|
export function unsafelyUnwrap(result) {
|
||
|
return result.unsafelyUnwrap();
|
||
|
}
|
||
|
/** Alias for [`unsafelyUnwrap`](#unsafelyunwrap) */
|
||
|
export const unsafelyGet = unsafelyUnwrap;
|
||
|
/** Alias for [`unsafelyUnwrap`](#unsafelyunwrap) */
|
||
|
export const unsafeGet = unsafelyUnwrap;
|
||
|
/**
|
||
|
Get the error value out of the [`Result`](#result).
|
||
|
|
||
|
Returns the content of an `Err`, but **throws if the `Result` is `Ok`**.
|
||
|
Prefer to use [`unwrapOrElse`](#unwraporelse).
|
||
|
|
||
|
@param result
|
||
|
@throws Error If the `Result` instance is `Nothing`.
|
||
|
*/
|
||
|
export function unsafelyUnwrapErr(result) {
|
||
|
return result.unsafelyUnwrapErr();
|
||
|
}
|
||
|
/** Alias for [`unsafelyUnwrapErr`](#unsafelyunwraperr) */
|
||
|
export const unsafelyGetErr = unsafelyUnwrapErr;
|
||
|
export function unwrapOr(defaultValue, result) {
|
||
|
const op = (r) => (isOk(r) ? r.value : defaultValue);
|
||
|
return curry1(op, result);
|
||
|
}
|
||
|
/** Alias for [`unwrapOr`](#unwrapor) */
|
||
|
export const getOr = unwrapOr;
|
||
|
export function unwrapOrElse(orElseFn, result) {
|
||
|
const op = (r) => (isOk(r) ? r.value : orElseFn(r.error));
|
||
|
return curry1(op, result);
|
||
|
}
|
||
|
/** Alias for [`unwrapOrElse`](#unwraporelse) */
|
||
|
export const getOrElse = unwrapOrElse;
|
||
|
/**
|
||
|
Convert a [`Result`](#result) to a [`Maybe`](../modules/_maybe_.html#maybe).
|
||
|
|
||
|
The converted type will be [`Just`] if the `Result` is [`Ok`] or [`Nothing`]
|
||
|
if the `Result` is [`Err`]; the wrapped error value will be discarded.
|
||
|
|
||
|
[`Just`]: ../classes/_maybe_.just.html
|
||
|
[`Nothing`]: ../classes/_maybe_.nothing.html
|
||
|
[`Ok`]: ../classes/_result_.ok.html
|
||
|
[`Err`]: ../classes/_result_.err.html
|
||
|
|
||
|
@param result The `Result` to convert to a `Maybe`
|
||
|
@returns `Just` the value in `result` if it is `Ok`; otherwise `Nothing`
|
||
|
*/
|
||
|
export function toMaybe(result) {
|
||
|
return isOk(result) ? Maybe.just(result.value) : Maybe.nothing();
|
||
|
}
|
||
|
export function fromMaybe(errValue, maybe) {
|
||
|
const op = (m) => Maybe.isJust(m) ? ok(Maybe.unsafelyUnwrap(m)) : err(errValue);
|
||
|
return curry1(op, maybe);
|
||
|
}
|
||
|
/**
|
||
|
Create a `String` representation of a `result` instance.
|
||
|
|
||
|
An `Ok` instance will be printed as `Ok(<representation of the value>)`, and
|
||
|
an `Err` instance will be printed as `Err(<representation of the error>)`,
|
||
|
where the representation of the value or error is simply the value or error's
|
||
|
own `toString` representation. For example:
|
||
|
|
||
|
call | output
|
||
|
--------------------------------- | ----------------------
|
||
|
`toString(ok(42))` | `Ok(42)`
|
||
|
`toString(ok([1, 2, 3]))` | `Ok(1,2,3)`
|
||
|
`toString(ok({ an: 'object' }))` | `Ok([object Object])`n
|
||
|
`toString(err(42))` | `Err(42)`
|
||
|
`toString(err([1, 2, 3]))` | `Err(1,2,3)`
|
||
|
`toString(err({ an: 'object' }))` | `Err([object Object])`
|
||
|
|
||
|
@typeparam T The type of the wrapped value; its own `.toString` will be used
|
||
|
to print the interior contents of the `Just` variant.
|
||
|
@param maybe The value to convert to a string.
|
||
|
@returns The string representation of the `Maybe`.
|
||
|
*/
|
||
|
export const toString = (result) => {
|
||
|
const body = (isOk(result) ? result.value : result.error).toString();
|
||
|
return `${result.variant.toString()}(${body})`;
|
||
|
};
|
||
|
/**
|
||
|
* Create an `Object` representation of a `Result` instance.
|
||
|
*
|
||
|
* Useful for serialization. `JSON.stringify()` uses it.
|
||
|
*
|
||
|
* @param result The value to convert to JSON
|
||
|
* @returns The JSON representation of the `Result`
|
||
|
*/
|
||
|
export const toJSON = (result) => {
|
||
|
return result.isOk()
|
||
|
? { variant: result.variant, value: result.value }
|
||
|
: { variant: result.variant, error: result.error };
|
||
|
};
|
||
|
export function match(matcher, result) {
|
||
|
const op = (r) => mapOrElse(matcher.Err, matcher.Ok, r);
|
||
|
return curry1(op, result);
|
||
|
}
|
||
|
/** Alias for [`match`](#match) */
|
||
|
export const cata = match;
|
||
|
export function equals(resultB, resultA) {
|
||
|
return resultA !== undefined
|
||
|
? resultA.match({
|
||
|
Err: () => isErr(resultB),
|
||
|
Ok: a => isOk(resultB) && resultB.unsafelyUnwrap() === a,
|
||
|
})
|
||
|
: (curriedResultA) => curriedResultA.match({
|
||
|
Err: () => isErr(resultB),
|
||
|
Ok: a => isOk(resultB) && resultB.unsafelyUnwrap() === a,
|
||
|
});
|
||
|
}
|
||
|
export function ap(resultFn, result) {
|
||
|
const op = (r) => r.match({
|
||
|
Ok: val => resultFn.map(fn => fn(val)),
|
||
|
Err: e => Result.err(e),
|
||
|
});
|
||
|
return curry1(op, result);
|
||
|
}
|
||
|
/**
|
||
|
Determine whether an item is an instance of `Just` or `Nothing`.
|
||
|
|
||
|
@param item The item to check.
|
||
|
*/
|
||
|
export function isInstance(item) {
|
||
|
return item instanceof Ok || item instanceof Err;
|
||
|
}
|
||
|
export const Result = {
|
||
|
Variant,
|
||
|
Ok,
|
||
|
Err,
|
||
|
isOk,
|
||
|
isErr,
|
||
|
ok,
|
||
|
err,
|
||
|
tryOr,
|
||
|
tryOrElse,
|
||
|
map,
|
||
|
mapOr,
|
||
|
mapOrElse,
|
||
|
mapErr,
|
||
|
and,
|
||
|
andThen,
|
||
|
chain,
|
||
|
flatMap,
|
||
|
or,
|
||
|
orElse,
|
||
|
unsafelyUnwrap,
|
||
|
unsafelyGet,
|
||
|
unsafeGet,
|
||
|
unsafelyUnwrapErr,
|
||
|
unsafelyGetErr,
|
||
|
unwrapOr,
|
||
|
getOr,
|
||
|
unwrapOrElse,
|
||
|
getOrElse,
|
||
|
toMaybe,
|
||
|
fromMaybe,
|
||
|
toString,
|
||
|
toJSON,
|
||
|
match,
|
||
|
cata,
|
||
|
equals,
|
||
|
ap,
|
||
|
isInstance,
|
||
|
};
|
||
|
export default Result;
|
||
|
//# sourceMappingURL=result.js.map
|