Skip to content

Commit

Permalink
docs: Update README
Browse files Browse the repository at this point in the history
  • Loading branch information
yifanwww committed Sep 13, 2023
1 parent 5e13cd1 commit ef7850b
Show file tree
Hide file tree
Showing 3 changed files with 138 additions and 1 deletion.
128 changes: 128 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,131 @@
# rustlike-result

Rust-like Result for Javascript

## Install

```sh
npm install rustlike-result
yarn add rustlike-result
pnpm install rustlike-result
```

## Usage

This package implement a Rust-like `Result`, nearly all methods are similar to the [Result].

```ts
// TODO
```

[result]: https://doc.rust-lang.org/std/result/enum.Result.html

### About Rust `Option`

This package doesn't implement Rust-like `Option`. Handling `undefined`/`null` is not as hard as it was a few years ago, because right now we already have [proposal-optional-chaining] and [proposal-nullish-coalescing] to help handle it.

[proposal-optional-chaining]: https://github.com/tc39/proposal-optional-chaining
[proposal-nullish-coalescing]: https://github.com/tc39/proposal-nullish-coalescing

## The Implementations for `Result`

The Rust-like `Result` implements the following methods:

| Rust-like `Result` method | Rust `Result` method |
| :------------------------ | :--------------------- |
| isOk | [is_ok] |
| isOkAnd | [is_ok_and] |
| isErr | [is_err] |
| isErrAnd | [is_err_and] |
| ok | [ok] |
| err | [err] |
| map | [map] |
| mapOr | [map_or] |
| mapOrElse | [map_or_else] |
| mapErr | [map_err] |
| expect | [expect] |
| unwrap | [unwrap] |
| expectErr | [expect_err] |
| unwrapErr | [unwrap_err] |
| unwrapOr | [unwrap_or] |
| unwrapOrElse | [unwrap_or_else] |
| unwrapUnchecked | [unwrap_unchecked] |
| unwrapErrUnchecked | [unwrap_err_unchecked] |
| and | [and] |
| andThen | [and_then] |
| or | [or] |
| orElse | [or_else] |
| transpose | [transpose] |

Unlike Rust, JavaScript doesn't have the 'Ownership' feature, so some API like `as_ref` is not necessary. These implementations are not implemented:

```md
<!-- implementations -->
as_ref
as_mut
inspect (unstable)
inspect_err (unstable)
as_deref
as_deref_mut
iter
iter_mut
unwrap_or_default
into_ok (unstable)
into_err (unstable)
copied
cloned
flatten (unstable)

<!-- some of trait implementations -->
clone
clone_from
fmt
hash
```

[is_ok]: https://doc.rust-lang.org/std/result/enum.Result.html#method.is_ok
[is_ok_and]: https://doc.rust-lang.org/std/result/enum.Result.html#method.is_ok_and
[is_err]: https://doc.rust-lang.org/std/result/enum.Result.html#method.is_err
[is_err_and]: https://doc.rust-lang.org/std/result/enum.Result.html#method.is_err_and
[ok]: https://doc.rust-lang.org/std/result/enum.Result.html#method.ok
[err]: https://doc.rust-lang.org/std/result/enum.Result.html#method.err
[map]: https://doc.rust-lang.org/std/result/enum.Result.html#method.map
[map_or]: https://doc.rust-lang.org/std/result/enum.Result.html#method.map_or
[map_or_else]: https://doc.rust-lang.org/std/result/enum.Result.html#method.map_or_else
[map_err]: https://doc.rust-lang.org/std/result/enum.Result.html#method.map_err
[expect]: https://doc.rust-lang.org/std/result/enum.Result.html#method.expect
[unwrap]: https://doc.rust-lang.org/std/result/enum.Result.html#method.unwrap
[expect_err]: https://doc.rust-lang.org/std/result/enum.Result.html#method.expect_err
[unwrap_err]: https://doc.rust-lang.org/std/result/enum.Result.html#method.unwrap_err
[unwrap_or]: https://doc.rust-lang.org/std/result/enum.Result.html#method.unwrap_or
[unwrap_or_else]: https://doc.rust-lang.org/std/result/enum.Result.html#method.unwrap_or_else
[unwrap_unchecked]: https://doc.rust-lang.org/std/result/enum.Result.html#method.unwrap_unchecked
[unwrap_err_unchecked]: https://doc.rust-lang.org/std/result/enum.Result.html#method.unwrap_err_unchecked
[and]: https://doc.rust-lang.org/std/result/enum.Result.html#method.and
[and_then]: https://doc.rust-lang.org/std/result/enum.Result.html#method.and_then
[or]: https://doc.rust-lang.org/std/result/enum.Result.html#method.or
[or_else]: https://doc.rust-lang.org/std/result/enum.Result.html#method.or_else
[transpose]: https://doc.rust-lang.org/std/result/enum.Result.html#method.transpose

## More Methods
### equal

You can not just use `===` or `==` to compare `Result`, so `Result` itself provides an method call `equal` for that.

```javascript
expect(Ok(1).equal(Ok(1))).toBe(true);
expect(Ok('hello').equal(Ok('hello'))).toBe(true);

expect(Ok({ foo: 1 }).equal(Ok({ foo: 1 }))).toBe(false);
expect(Ok([1]).equal(Ok([1]))).toBe(false);
```

There is no built-in deep-equal support in this package for array, object and some built-in classes like `Date`. If you do want to deeply compare those complex structures, you will have to write your own helper functions.

There is a [proposal] (stage 2) that introduces `Record` and `Tuple` which are compared by content rather than identity. In the future, we can use `Record` and `Tuple` in `Result` so that we don't need to implement custom equality comparison function.

[proposal]: https://github.com/tc39/proposal-record-tuple

## License

MIT
9 changes: 9 additions & 0 deletions src/__tests__/result.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -418,5 +418,14 @@ describe(`Test method \`${RustlikeResult.name}.prototype.${RustlikeResult.protot
expect(Err(Ok<number, string>(1)).equal(Err(Err('Some error message')))).toBe(false);
expect(Err(Err<number, string>('Some error message')).equal(Err(Ok(1)))).toBe(false);
expect(Ok<number, string>(1).equal(Err('Some error message'))).toBe(false);

expect(Ok([1]).equal(Ok([1]))).toBe(false);
expect(Ok({ foo: 1 }).equal(Ok({ foo: 1 }))).toBe(false);
expect(Ok(Ok([1])).equal(Ok(Ok([1])))).toBe(false);
expect(Ok(Ok({ foo: 1 })).equal(Ok(Ok({ foo: 1 })))).toBe(false);
expect(Err({ message: 'Some error message' }).equal(Err({ message: 'Some error message' }))).toBe(false);
expect(Err(Err({ message: 'Some error message' })).equal(Err(Err({ message: 'Some error message' })))).toBe(
false,
);
});
});
2 changes: 1 addition & 1 deletion src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
* - https://github.com/tc39/proposal-optional-chaining
* - https://github.com/tc39/proposal-nullish-coalescing
*
* We don't need Rust-like Option anymore in most cases.
* We don't need Rust-like Option anymore in most cases unless we want functional programming.
*
* This type doesn't use the name `Option`,
* by giving it a different name we can easily know that this is not Rust-like Option.
Expand Down

0 comments on commit ef7850b

Please sign in to comment.