Skip to content

Commit

Permalink
feat: add examples for inspect, inspectAsync, inspectErr, inspectErrA…
Browse files Browse the repository at this point in the history
…sync
  • Loading branch information
yifanwww committed Mar 23, 2024
1 parent 0822941 commit 1a44c57
Show file tree
Hide file tree
Showing 4 changed files with 251 additions and 6 deletions.
78 changes: 76 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,10 @@ Rust-like `Result` for JavaScript.
- [mapOrElseAsync](#maporelseasync)
- [mapErr](#maperr)
- [mapErrAsync](#maperrasync)
- [inspect](#inspect)
- [inspectAsync](#inspectasync)
- [inspectErr](#inspecterr)
- [inspectErrAsync](#inspecterrasync)
- [Additional Methods](#additional-methods)
- [equal](#equal)
- [Helpers for Resultifying](#helpers-for-resultifying)
Expand Down Expand Up @@ -341,7 +345,7 @@ This function can be used to compose the results of two functions.
Examples:

```ts
import { Ok, type Result } from 'rustlike-result';
import { Ok } from 'rustlike-result';

const x = await Ok<string, string>('foo').mapAsync((value) => Promise.resolve(value.length));
assert(x.ok() === 3);
Expand Down Expand Up @@ -447,12 +451,82 @@ This function can be used to pass through a successful result while handling an
Examples:

```ts
import { Err, type Result } from 'rustlike-result';
import { Err } from 'rustlike-result';

const x = await Err(new Error('Some error message')).mapErrAsync((err) => Promise.resolve(err.message));
assert(x.err() === 'Some error message');
```

#### `inspect`

Calls the provided closure with a reference to the contained value if `Ok`.

Examples:

```ts
import { resultify } from 'rustlike-result';

const num = resultify
.sync<SyntaxError>()(JSON.parse)('4')
.inspect((value: number) => console.log(`original: ${value}`))
.map((value) => value ** 3)
.expect('failed to parse number');
assert(num === 64);
```

#### `inspectAsync`

Asynchronously calls the provided closure with a reference to the contained value if `Ok`.

Examples:

```ts
import { resultify } from 'rustlike-result';

const num = await resultify
.sync<SyntaxError>()(JSON.parse)('4')
.inspectAsync((value: number) => {
console.log(`original: ${value}`);
return Promise.resolve();
})
.then((result) => result.map((value) => value ** 3))
.then((result) => result.expect('failed to parse number'));
assert(num === 64);
```

#### `inspectErr`

Calls the provided closure with a reference to the contained value if `Err`.

Examples:

```ts
import { resultify } from 'rustlike-result';

const num = resultify
.sync<SyntaxError>()(JSON.parse)('asdf')
.inspectErr((err) => console.log(`failed to parse json string: ${err.message}`));
assert(num.err() instanceof SyntaxError);
```

#### `inspectErrAsync`

Asynchronously calls the provided closure with a reference to the contained value if `Err`.

Examples:

```ts
import { resultify } from 'rustlike-result';

const num = await resultify
.sync<SyntaxError>()(JSON.parse)('asdf')
.inspectErrAsync((err) => {
console.log(`failed to parse json string: ${err.message}`);
return Promise.resolve();
});
assert(num.err() instanceof SyntaxError);
```

### Additional Methods
#### equal

Expand Down
63 changes: 63 additions & 0 deletions src/__tests__/result.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import assert from 'node:assert';

import { Err, Ok } from '../factory';
import { RustlikeResult } from '../result';
import { resultify } from '../resultify';
import type { Result } from '../types';

function panicFn1(): never {
Expand Down Expand Up @@ -761,6 +762,21 @@ describe(`Test method \`${RustlikeResult.name}.prototype.${RustlikeResult.protot
it('should panic if fn panic', () => {
expect(() => Ok(1).inspect(panicFn1)).toThrow(Error('error'));
});

it('should have correct examples doc', () => {
jest.spyOn(console, 'log').mockImplementationOnce(() => {});

function examples() {
const num = resultify
.sync<SyntaxError>()(JSON.parse)('4')
.inspect((value: number) => console.log(`original: ${value}`))
.map((value) => value ** 3)
.expect('failed to parse number');
assert(num === 64);
}

expect(examples).not.toThrow();
});
});

describe(`Test method \`${RustlikeResult.name}.prototype.${RustlikeResult.prototype.inspectAsync.name}\``, () => {
Expand Down Expand Up @@ -809,6 +825,24 @@ describe(`Test method \`${RustlikeResult.name}.prototype.${RustlikeResult.protot
await expect(() => Ok(1).inspectAsync(panicFn1)).rejects.toThrow(Error('error'));
await expect(() => Ok(1).inspectAsync(panicFn2)).rejects.toThrow(Error('error'));
});

it('should have correct examples doc', async () => {
async function examples() {
jest.spyOn(console, 'log').mockImplementationOnce(() => {});

const num = await resultify
.sync<SyntaxError>()(JSON.parse)('4')
.inspectAsync((value: number) => {
console.log(`original: ${value}`);
return Promise.resolve();
})
.then((result) => result.map((value) => value ** 3))
.then((result) => result.expect('failed to parse number'));
assert(num === 64);
}

await expect(examples()).resolves.not.toThrow();
});
});

describe(`Test method \`${RustlikeResult.name}.prototype.${RustlikeResult.prototype.inspectErr.name}\``, () => {
Expand Down Expand Up @@ -841,6 +875,19 @@ describe(`Test method \`${RustlikeResult.name}.prototype.${RustlikeResult.protot
it('should panic if fn panic', () => {
expect(() => Err('err').inspectErr(panicFn1)).toThrow(Error('error'));
});

it('should have correct examples doc', () => {
jest.spyOn(console, 'log').mockImplementationOnce(() => {});

function examples() {
const num = resultify
.sync<SyntaxError>()(JSON.parse)('asdf')
.inspectErr((err) => console.log(`failed to parse json string: ${err.message}`));
assert(num.err() instanceof SyntaxError);
}

expect(examples).not.toThrow();
});
});

describe(`Test method \`${RustlikeResult.name}.prototype.${RustlikeResult.prototype.inspectErrAsync.name}\``, () => {
Expand Down Expand Up @@ -889,6 +936,22 @@ describe(`Test method \`${RustlikeResult.name}.prototype.${RustlikeResult.protot
await expect(() => Err('err').inspectErrAsync(panicFn1)).rejects.toThrow(Error('error'));
await expect(() => Err('err').inspectErrAsync(panicFn2)).rejects.toThrow(Error('error'));
});

it('should have correct examples doc', async () => {
jest.spyOn(console, 'log').mockImplementationOnce(() => {});

async function examples() {
const num = await resultify
.sync<SyntaxError>()(JSON.parse)('asdf')
.inspectErrAsync((err) => {
console.log(`failed to parse json string: ${err.message}`);
return Promise.resolve();
});
assert(num.err() instanceof SyntaxError);
}

await expect(examples()).resolves.not.toThrow();
});
});

describe(`Test method \`${RustlikeResult.name}.prototype.${RustlikeResult.prototype.expect.name}\``, () => {
Expand Down
58 changes: 56 additions & 2 deletions src/result.ts
Original file line number Diff line number Diff line change
Expand Up @@ -259,7 +259,7 @@ export class RustlikeResult<T, E> implements Result<T, E> {
* Examples:
*
* ```
* import { Ok, type Result } from 'rustlike-result';
* import { Ok } from 'rustlike-result';
*
* const x = await Ok<string, string>('foo').mapAsync((value) => Promise.resolve(value.length));
* assert(x.ok() === 3);
Expand Down Expand Up @@ -404,7 +404,7 @@ export class RustlikeResult<T, E> implements Result<T, E> {
* Examples:
*
* ```
* import { Err, type Result } from 'rustlike-result';
* import { Err } from 'rustlike-result';
*
* const x = await Err(new Error('Some error message')).mapErrAsync((err) => Promise.resolve(err.message));
* assert(x.err() === 'Some error message');
Expand All @@ -419,6 +419,19 @@ export class RustlikeResult<T, E> implements Result<T, E> {
/**
* Calls the provided closure with a reference to the contained value if `Ok`.
*
* Examples:
*
* ```
* import { resultify } from 'rustlike-result';
*
* const num = resultify
* .sync<SyntaxError>()(JSON.parse)('4')
* .inspect((value: number) => console.log(`original: ${value}`))
* .map((value) => value ** 3)
* .expect('failed to parse number');
* assert(num === 64);
* ```
*
* ref: https://doc.rust-lang.org/std/result/enum.Result.html#method.inspect
*/
inspect(fn: (value: T) => void): this {
Expand All @@ -431,6 +444,22 @@ export class RustlikeResult<T, E> implements Result<T, E> {
/**
* Asynchronously calls the provided closure with a reference to the contained value if `Ok`.
*
* Examples:
*
* ```
* import { resultify } from 'rustlike-result';
*
* const num = await resultify
* .sync<SyntaxError>()(JSON.parse)('4')
* .inspectAsync((value: number) => {
* console.log(`original: ${value}`);
* return Promise.resolve();
* })
* .then((result) => result.map((value) => value ** 3))
* .then((result) => result.expect('failed to parse number'));
* assert(num === 64);
* ```
*
* ref: https://doc.rust-lang.org/std/result/enum.Result.html#method.inspect
*/
async inspectAsync(fn: (value: T) => void | Promise<void>): Promise<this> {
Expand All @@ -443,6 +472,17 @@ export class RustlikeResult<T, E> implements Result<T, E> {
/**
* Calls the provided closure with a reference to the contained value if `Err`.
*
* Examples:
*
* ```
* import { resultify } from 'rustlike-result';
*
* const num = resultify
* .sync<SyntaxError>()(JSON.parse)('asdf')
* .inspectErr((err) => console.log(`failed to parse json string: ${err.message}`));
* assert(num.err() instanceof SyntaxError);
* ```
*
* ref: https://doc.rust-lang.org/std/result/enum.Result.html#method.inspect_err
*/
inspectErr(fn: (err: E) => void): this {
Expand All @@ -455,6 +495,20 @@ export class RustlikeResult<T, E> implements Result<T, E> {
/**
* Asynchronously calls the provided closure with a reference to the contained value if `Err`.
*
* Examples:
*
* ```
* import { resultify } from 'rustlike-result';
*
* const num = await resultify
* .sync<SyntaxError>()(JSON.parse)('asdf')
* .inspectErrAsync((err) => {
* console.log(`failed to parse json string: ${err.message}`);
* return Promise.resolve();
* });
* assert(num.err() instanceof SyntaxError);
* ```
*
* ref: https://doc.rust-lang.org/std/result/enum.Result.html#method.inspect_err
*/
async inspectErrAsync(fn: (err: E) => void | Promise<void>): Promise<this> {
Expand Down
Loading

0 comments on commit 1a44c57

Please sign in to comment.