Skip to content

Commit

Permalink
rename mapResult to mapOkToResult & add mapErrorToResult
Browse files Browse the repository at this point in the history
bloodyowl committed Apr 25, 2023
1 parent 9101dde commit e00b0c0
Showing 8 changed files with 191 additions and 54 deletions.
6 changes: 6 additions & 0 deletions HISTORY.md
Original file line number Diff line number Diff line change
@@ -4,6 +4,12 @@ Changes:

- Don't default error types to initial ones in `flatMap`-like methods (29d3307)

# 0.12.1

Features:

- Add `Array.keepMapOne` (a8300de)

# 0.12.0

Features:
63 changes: 44 additions & 19 deletions docs/docs/async-data-result.md
Original file line number Diff line number Diff line change
@@ -11,28 +11,50 @@ You can still use all the regular [AsyncData](./async-data) methods. The followi

## Methods

### .mapResult(f)
### .mapOkToResult(f)

```ts
AsyncData<Result<A, E>>.mapResult<B, F>(
AsyncData<Result<A, E>>.mapOkToResult<B, F>(
func: (value: A) => Result<B, F>,
): AsyncData<Result<B, E | F>>
```

Takes a `AsyncData<Result<Ok, Error>>` and a `f` function taking `Ok` and returning `Result<ReturnValue, Error>` and returns a new `AsyncData<Result<ReturnValue, Error>>`

```ts title="Examples"
AsyncData.Done(Result.Ok(3)).mapResult((ok) => {
AsyncData.Done(Result.Ok(3)).mapOkToResult((ok) => {
return Result.Ok(ok * 2);
});
// AsyncData<Result.Ok<6>>

AsyncData.Done(Result.Ok(3)).mapResult((ok) =>
AsyncData.Done(Result.Ok(3)).mapOkToResult((ok) =>
isEven(ok) ? Result.Ok(ok) : Result.Error("Odd number");
);
// AsyncData<Result.Error<"Odd number">>
```

### .mapErrorToResult(f)

```ts
AsyncData<Result<A, E>>.mapErrorToResult<B, F>(
func: (value: E) => Result<B, F>,
): AsyncData<Result<A | B, F>>
```

Takes a `AsyncData<Result<Ok, Error>>` and a `f` function taking `Error` and returning `Result<ReturnValue, Error>` and returns a new `AsyncData<Result<ReturnValue, Error>>`

```ts title="Examples"
AsyncData.Done(Result.Error(3)).mapErrorToResult((error) => {
return Result.Ok(ok * 2);
});
// AsyncData<Result.Ok<6>>

AsyncData.Done(Result.Error(3)).mapErrorToResult((error) =>
isEven(error) ? Result.Ok(error) : Result.Error("Odd number");
);
// AsyncData<Result.Error<"Odd number">>
```

### .mapOk(f)

```ts
@@ -133,18 +155,21 @@ AsyncData.Done(Result.Error("Error")).flatMapError((error) =>

## Cheatsheet

| Method | Input | Function input | Function output | Returned value |
| -------------------------------- | --------------------- | -------------- | --------------------- | --------------------- |
| [`mapResult`](#mapresultf) | `AsyncData(Ok(x))` | `x` | `Ok(y)` | `AsyncData(Ok(y))` |
| [`mapResult`](#mapresultf) | `AsyncData(Ok(x))` | `x` | `Error(f)` | `AsyncData(Error(f))` |
| [`mapResult`](#mapresultf) | `AsyncData(Error(e))` | _not provided_ | _not executed_ | `AsyncData(Error(e))` |
| [`mapOk`](#mapokf) | `AsyncData(Ok(x))` | `x` | `y` | `AsyncData(Ok(y))` |
| [`mapOk`](#mapokf) | `AsyncData(Error(e))` | _not provided_ | _not executed_ | `AsyncData(Error(e))` |
| [`mapError`](#maperrorf) | `AsyncData(Ok(x))` | _not provided_ | _not executed_ | `AsyncData(Ok(x))` |
| [`mapError`](#maperrorf) | `AsyncData(Error(e))` | `e` | `f` | `AsyncData(Error(f))` |
| [`flatMapOk`](#flatmapokf) | `AsyncData(Ok(x))` | `x` | `AsyncData(Ok(y))` | `AsyncData(Ok(y))` |
| [`flatMapOk`](#flatmapokf) | `AsyncData(Ok(x))` | `x` | `AsyncData(Error(f))` | `AsyncData(Error(f))` |
| [`flatMapOk`](#flatmapokf) | `AsyncData(Error(e))` | _not provided_ | _not executed_ | `AsyncData(Error(e))` |
| [`flatMapError`](#flatmaperrorf) | `AsyncData(Ok(x))` | _not provided_ | _not executed_ | `AsyncData(Ok(x))` |
| [`flatMapError`](#flatmaperrorf) | `AsyncData(Error(e))` | `e` | `AsyncData(Ok(y))` | `AsyncData(Ok(y))` |
| [`flatMapError`](#flatmaperrorf) | `AsyncData(Error(e))` | `e` | `AsyncData(Error(f))` | `AsyncData(Error(f))` |
| Method | Input | Function input | Function output | Returned value |
| ---------------------------------------- | --------------------- | -------------- | --------------------- | --------------------- |
| [`mapOkToResult`](#mapoktoresultf) | `AsyncData(Ok(x))` | `x` | `Ok(y)` | `AsyncData(Ok(y))` |
| [`mapOkToResult`](#mapoktoresultf) | `AsyncData(Ok(x))` | `x` | `Error(f)` | `AsyncData(Error(f))` |
| [`mapOkToResult`](#mapoktoresultf) | `AsyncData(Error(e))` | _not provided_ | _not executed_ | `AsyncData(Error(e))` |
| [`mapErrorToResult`](#maperrortoresultf) | `AsyncData(Error(e))` | `e` | `Ok(y)` | `AsyncData(Ok(y))` |
| [`mapErrorToResult`](#maperrortoresultf) | `AsyncData(Error(e))` | `e` | `Error(f)` | `AsyncData(Error(f))` |
| [`mapErrorToResult`](#maperrortoresultf) | `AsyncData(Ok(x))` | _not provided_ | _not executed_ | `AsyncData(Ok(x))` |
| [`mapOk`](#mapokf) | `AsyncData(Ok(x))` | `x` | `y` | `AsyncData(Ok(y))` |
| [`mapOk`](#mapokf) | `AsyncData(Error(e))` | _not provided_ | _not executed_ | `AsyncData(Error(e))` |
| [`mapError`](#maperrorf) | `AsyncData(Ok(x))` | _not provided_ | _not executed_ | `AsyncData(Ok(x))` |
| [`mapError`](#maperrorf) | `AsyncData(Error(e))` | `e` | `f` | `AsyncData(Error(f))` |
| [`flatMapOk`](#flatmapokf) | `AsyncData(Ok(x))` | `x` | `AsyncData(Ok(y))` | `AsyncData(Ok(y))` |
| [`flatMapOk`](#flatmapokf) | `AsyncData(Ok(x))` | `x` | `AsyncData(Error(f))` | `AsyncData(Error(f))` |
| [`flatMapOk`](#flatmapokf) | `AsyncData(Error(e))` | _not provided_ | _not executed_ | `AsyncData(Error(e))` |
| [`flatMapError`](#flatmaperrorf) | `AsyncData(Ok(x))` | _not provided_ | _not executed_ | `AsyncData(Ok(x))` |
| [`flatMapError`](#flatmaperrorf) | `AsyncData(Error(e))` | `e` | `AsyncData(Ok(y))` | `AsyncData(Ok(y))` |
| [`flatMapError`](#flatmaperrorf) | `AsyncData(Error(e))` | `e` | `AsyncData(Error(f))` | `AsyncData(Error(f))` |
64 changes: 45 additions & 19 deletions docs/docs/future-result.md
Original file line number Diff line number Diff line change
@@ -11,10 +11,10 @@ You can still use all the regular [Future](./future) methods. The following help

## Methods

### .mapResult(f)
### .mapOkToResult(f)

```ts
Future<Result<A, E>>.mapResult<B, F>(
Future<Result<A, E>>.mapOkToResult<B, F>(
func: (value: A) => Result<B, F>,
propagateCancel?: boolean
): Future<Result<B, E | F>>
@@ -23,12 +23,35 @@ Future<Result<A, E>>.mapResult<B, F>(
Takes a `Future<Result<Ok, Error>>` and a `f` function taking `Ok` and returning `Result<ReturnValue, Error>` and returns a new `Future<Result<ReturnValue, Error>>`

```ts title="Examples"
Future.value(Result.Ok(3)).mapResult((ok) => {
Future.value(Result.Ok(3)).mapOkToResult((ok) => {
return Result.Ok(ok * 2);
});
// Future<Result.Ok<6>>

Future.value(Result.Ok(3)).mapResult((ok) =>
Future.value(Result.Ok(3)).mapOkToResult((ok) =>
isEven(ok) ? Result.Ok(ok) : Result.Error("Odd number");
);
// Future<Result.Error<"Odd number">>
```

### .mapErrorToResult(f)

```ts
Future<Result<A, E>>.mapErrorToResult<B, F>(
func: (value: E) => Result<B, F>,
propagateCancel?: boolean
): Future<Result<A | B, F>>
```

Takes a `Future<Result<Ok, Error>>` and a `f` function taking `Error` and returning `Result<ReturnValue, Error>` and returns a new `Future<Result<ReturnValue, Error>>`

```ts title="Examples"
Future.value(Result.Error(3)).mapErrorToResult((ok) => {
return Result.Ok(ok * 2);
});
// Future<Result.Ok<6>>

Future.value(Result.Error(3)).mapErrorToResult((ok) =>
isEven(ok) ? Result.Ok(ok) : Result.Error("Odd number");
);
// Future<Result.Error<"Odd number">>
@@ -248,18 +271,21 @@ const step2 = f.map(Result.all);

## Cheatsheet

| Method | Input | Function input | Function output | Returned value |
| -------------------------------- | ------------------ | -------------- | ------------------ | ------------------ |
| [`mapResult`](#mapresultf) | `Future(Ok(x))` | `x` | `Ok(y)` | `Future(Ok(y))` |
| [`mapResult`](#mapresultf) | `Future(Ok(x))` | `x` | `Error(f)` | `Future(Error(f))` |
| [`mapResult`](#mapresultf) | `Future(Error(e))` | _not provided_ | _not executed_ | `Future(Error(e))` |
| [`mapOk`](#mapokf) | `Future(Ok(x))` | `x` | `y` | `Future(Ok(y))` |
| [`mapOk`](#mapokf) | `Future(Error(e))` | _not provided_ | _not executed_ | `Future(Error(e))` |
| [`mapError`](#maperrorf) | `Future(Ok(x))` | _not provided_ | _not executed_ | `Future(Ok(x))` |
| [`mapError`](#maperrorf) | `Future(Error(e))` | `e` | `f` | `Future(Error(f))` |
| [`flatMapOk`](#flatmapokf) | `Future(Ok(x))` | `x` | `Future(Ok(y))` | `Future(Ok(y))` |
| [`flatMapOk`](#flatmapokf) | `Future(Ok(x))` | `x` | `Future(Error(f))` | `Future(Error(f))` |
| [`flatMapOk`](#flatmapokf) | `Future(Error(e))` | _not provided_ | _not executed_ | `Future(Error(e))` |
| [`flatMapError`](#flatmaperrorf) | `Future(Ok(x))` | _not provided_ | _not executed_ | `Future(Ok(x))` |
| [`flatMapError`](#flatmaperrorf) | `Future(Error(e))` | `e` | `Future(Ok(y))` | `Future(Ok(y))` |
| [`flatMapError`](#flatmaperrorf) | `Future(Error(e))` | `e` | `Future(Error(f))` | `Future(Error(f))` |
| Method | Input | Function input | Function output | Returned value |
| ---------------------------------------- | ------------------ | -------------- | ------------------ | ------------------ |
| [`mapOkToResult`](#mapoktoresultf) | `Future(Ok(x))` | `x` | `Ok(y)` | `Future(Ok(y))` |
| [`mapOkToResult`](#mapoktoresultf) | `Future(Ok(x))` | `x` | `Error(f)` | `Future(Error(f))` |
| [`mapOkToResult`](#mapoktoresultf) | `Future(Error(e))` | _not provided_ | _not executed_ | `Future(Error(e))` |
| [`mapErrorToResult`](#maperrortoresultf) | `Future(Error(e))` | `e` | `Ok(y)` | `Future(Ok(y))` |
| [`mapErrorToResult`](#maperrortoresultf) | `Future(Error(e))` | `e` | `Error(f)` | `Future(Error(f))` |
| [`mapErrorToResult`](#maperrortoresultf) | `Future(Ok(x))` | _not provided_ | _not executed_ | `Future(Ok(x))` |
| [`mapOk`](#mapokf) | `Future(Ok(x))` | `x` | `y` | `Future(Ok(y))` |
| [`mapOk`](#mapokf) | `Future(Error(e))` | _not provided_ | _not executed_ | `Future(Error(e))` |
| [`mapError`](#maperrorf) | `Future(Ok(x))` | _not provided_ | _not executed_ | `Future(Ok(x))` |
| [`mapError`](#maperrorf) | `Future(Error(e))` | `e` | `f` | `Future(Error(f))` |
| [`flatMapOk`](#flatmapokf) | `Future(Ok(x))` | `x` | `Future(Ok(y))` | `Future(Ok(y))` |
| [`flatMapOk`](#flatmapokf) | `Future(Ok(x))` | `x` | `Future(Error(f))` | `Future(Error(f))` |
| [`flatMapOk`](#flatmapokf) | `Future(Error(e))` | _not provided_ | _not executed_ | `Future(Error(e))` |
| [`flatMapError`](#flatmaperrorf) | `Future(Ok(x))` | _not provided_ | _not executed_ | `Future(Ok(x))` |
| [`flatMapError`](#flatmaperrorf) | `Future(Error(e))` | `e` | `Future(Ok(y))` | `Future(Ok(y))` |
| [`flatMapError`](#flatmaperrorf) | `Future(Error(e))` | `e` | `Future(Error(f))` | `Future(Error(f))` |
31 changes: 29 additions & 2 deletions src/AsyncData.ts
Original file line number Diff line number Diff line change
@@ -26,11 +26,21 @@ interface IAsyncData<A> {
*
* (AsyncData\<Result<A, E>>, A => \<Result<B, F>) => AsyncData\<Result<B, F | E>>
*/
mapResult<A, E, B, F>(
mapOkToResult<A, E, B, F>(
this: AsyncData<Result<A, E>>,
func: (value: A) => Result<B, F>,
): AsyncData<Result<B, F | E>>;

/**
* Takes a callback taking the Ok value and returning a new result and returns an AsyncData with this new result
*
* (AsyncData\<Result<A, E>>, E => \<Result<B, F>) => AsyncData\<Result<A | B, F>>
*/
mapErrorToResult<A, E, B, F>(
this: AsyncData<Result<A, E>>,
func: (value: E) => Result<B, F>,
): AsyncData<Result<A | B, F>>;

/**
* Takes a callback taking the Ok value and returning a new ok value and returns an AsyncData resolving to this new result
*
@@ -159,7 +169,7 @@ const asyncDataProto = (<A>(): IAsyncData<A> => ({
*
* Takes a callback taking the Ok value and returning a new result and returns an AsyncData with this new result
*/
mapResult<A, E, B, F>(
mapOkToResult<A, E, B, F>(
this: AsyncData<Result<A, E>>,
func: (value: A) => Result<B, F>,
): AsyncData<Result<B, F | E>> {
@@ -171,6 +181,23 @@ const asyncDataProto = (<A>(): IAsyncData<A> => ({
});
},

/**
* For AsyncData<Result<*>>:
*
* Takes a callback taking the Error value and returning a new result and returns an AsyncData with this new result
*/
mapErrorToResult<A, E, B, F>(
this: AsyncData<Result<A, E>>,
func: (value: E) => Result<B, F>,
): AsyncData<Result<A | B, F>> {
return this.map((value) => {
return value.match({
Error: (error) => func(error),
Ok: () => value as unknown as Result<A | B, F>,
});
});
},

/**
* For AsyncData<Result<*>>:
*
20 changes: 19 additions & 1 deletion src/Future.ts
Original file line number Diff line number Diff line change
@@ -264,7 +264,7 @@ export class Future<A> {
*
* Takes a callback taking the Ok value and returning a new result and returns a future resolving to this new result
*/
mapResult<A, E, B, F>(
mapOkToResult<A, E, B, F>(
this: Future<Result<A, E>>,
func: (value: A) => Result<B, F>,
propagateCancel = false,
@@ -277,6 +277,24 @@ export class Future<A> {
}, propagateCancel);
}

/**
* For Future<Result<*>>:
*
* Takes a callback taking the Error value and returning a new result and returns a future resolving to this new result
*/
mapErrorToResult<A, E, B, F>(
this: Future<Result<A, E>>,
func: (value: E) => Result<B, F>,
propagateCancel = false,
): Future<Result<A | B, F>> {
return this.map((value) => {
return value.match({
Error: (error) => func(error),
Ok: () => value as unknown as Result<A | B, F>,
});
}, propagateCancel);
}

/**
* For Future<Result<*>>:
*
33 changes: 27 additions & 6 deletions test/AsyncData.test.ts
Original file line number Diff line number Diff line change
@@ -275,27 +275,48 @@ test("Future mapError ok", async () => {
expect(result).toEqual(AsyncData.Done(Result.Ok("one")));
});

test("Future mapResult", async () => {
const result = AsyncData.Done(Result.Ok("one")).mapResult((x) =>
test("Future mapOkToResult", async () => {
const result = AsyncData.Done(Result.Ok("one")).mapOkToResult((x) =>
Result.Ok(`${x}!`),
);
expect(result).toEqual(AsyncData.Done(Result.Ok("one!")));
});

test("Future mapResult", async () => {
const result = AsyncData.Done(Result.Error("one")).mapResult((x) =>
test("Future mapOkToResult", async () => {
const result = AsyncData.Done(Result.Error("one")).mapOkToResult((x) =>
Result.Ok(`${x}!`),
);
expect(result).toEqual(AsyncData.Done(Result.Error("one")));
});

test("Future mapResult", async () => {
const result = AsyncData.Done(Result.Ok("one")).mapResult((x) =>
test("Future mapOkToResult", async () => {
const result = AsyncData.Done(Result.Ok("one")).mapOkToResult((x) =>
Result.Error(`${x}!`),
);
expect(result).toEqual(AsyncData.Done(Result.Error("one!")));
});

test("Future mapErrorToResult", async () => {
const result = AsyncData.Done(Result.Error("one")).mapErrorToResult((x) =>
Result.Ok(`${x}!`),
);
expect(result).toEqual(AsyncData.Done(Result.Ok("one!")));
});

test("Future mapErrorToResult", async () => {
const result = AsyncData.Done(Result.Ok("one")).mapErrorToResult((x) =>
Result.Ok(`${x}!`),
);
expect(result).toEqual(AsyncData.Done(Result.Ok("one")));
});

test("Future mapErrorToResult", async () => {
const result = AsyncData.Done(Result.Error("one")).mapErrorToResult((x) =>
Result.Ok(`${x}!`),
);
expect(result).toEqual(AsyncData.Done(Result.Ok("one!")));
});

test("Future flatMapOk", async () => {
const result = AsyncData.Done(Result.Ok("one")).flatMapOk((x) =>
AsyncData.Done(Result.Ok(`${x}!`)),
22 changes: 18 additions & 4 deletions test/Future.test.ts
Original file line number Diff line number Diff line change
@@ -112,20 +112,34 @@ test("Future mapError ok", async () => {
expect(result).toEqual(Result.Ok("one"));
});

test("Future mapResult", async () => {
const result = await Future.value(Result.Ok("one")).mapResult((x) =>
test("Future mapOkToResult", async () => {
const result = await Future.value(Result.Ok("one")).mapOkToResult((x) =>
Result.Ok(`${x}!`),
);
expect(result).toEqual(Result.Ok("one!"));
});

test("Future mapResult error", async () => {
const result = await Future.value(Result.Error("one")).mapResult((x) =>
test("Future mapOkToResult error", async () => {
const result = await Future.value(Result.Error("one")).mapOkToResult((x) =>
Result.Ok(`${x}!`),
);
expect(result).toEqual(Result.Error("one"));
});

test("Future mapErrorToResult", async () => {
const result = await Future.value(Result.Error("one")).mapErrorToResult((x) =>
Result.Error(`${x}!`),
);
expect(result).toEqual(Result.Error("one!"));
});

test("Future mapErrorToResult ok", async () => {
const result = await Future.value(Result.Ok("one")).mapErrorToResult((x) =>
Result.Error(`${x}!`),
);
expect(result).toEqual(Result.Ok("one"));
});

test("Future flatMapOk", async () => {
const result = await Future.value(Result.Ok("one")).flatMapOk((x) =>
Future.value(Result.Ok(`${x}!`)),
6 changes: 3 additions & 3 deletions yarn.lock
Original file line number Diff line number Diff line change
@@ -3718,9 +3718,9 @@ typed-array-length@^1.0.4:
is-typed-array "^1.1.9"

typescript@^4.1.3:
version "4.9.5"
resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.9.5.tgz#095979f9bcc0d09da324d58d03ce8f8374cbe65a"
integrity sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==
version "4.7.4"
resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.7.4.tgz#1a88596d1cf47d59507a1bcdfb5b9dfe4d488235"
integrity sha512-C0WQT0gezHuw6AdY1M2jxUO83Rjf0HP7Sk1DtXj6j1EwkQNZrHAg2XPWlq62oqEhYvONq5pkC2Y9oPljWToLmQ==

typescript@^5.0.4:
version "5.0.4"

0 comments on commit e00b0c0

Please sign in to comment.