rsult 1.4.0 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +7 -6
- package/readme.md +161 -5
- package/rust/option.rs +2822 -0
- package/rust/result.rs +2207 -0
- package/src/lib.ts +3 -1
- package/src/option-async.test.ts +410 -0
- package/src/option-async.ts +467 -0
- package/src/option.test.ts +101 -0
- package/src/option.ts +480 -266
- package/src/result-async.test.ts +485 -0
- package/src/result-async.ts +635 -0
- package/src/result.test.ts +36 -0
- package/src/result.ts +418 -340
- package/src/types.test.ts +409 -0
- package/dist/lib.d.ts +0 -2
- package/dist/lib.js +0 -19
- package/dist/lib.js.map +0 -1
- package/dist/option.d.ts +0 -307
- package/dist/option.js +0 -195
- package/dist/option.js.map +0 -1
- package/dist/result.d.ts +0 -410
- package/dist/result.js +0 -231
- package/dist/result.js.map +0 -1
package/package.json
CHANGED
|
@@ -1,18 +1,19 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "rsult",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "2.0.0",
|
|
4
4
|
"description": "",
|
|
5
5
|
"main": "dist/lib.js",
|
|
6
6
|
"types": "dist/lib.d.ts",
|
|
7
|
-
"repository": "https://github.com/
|
|
7
|
+
"repository": "https://github.com/19h/rsult",
|
|
8
8
|
"keywords": [],
|
|
9
9
|
"author": "Kenan Sulayman <kenan@sly.mn>",
|
|
10
10
|
"license": "MIT",
|
|
11
11
|
"devDependencies": {
|
|
12
|
-
"@swc/core": "^1.
|
|
13
|
-
"@swc/jest": "^0.2.
|
|
14
|
-
"@types/jest": "^
|
|
15
|
-
"jest": "^
|
|
12
|
+
"@swc/core": "^1.15.7",
|
|
13
|
+
"@swc/jest": "^0.2.39",
|
|
14
|
+
"@types/jest": "^30.0.0",
|
|
15
|
+
"jest": "^30.2.0",
|
|
16
|
+
"typescript": "^5.9.3"
|
|
16
17
|
},
|
|
17
18
|
"scripts": {
|
|
18
19
|
"test": "echo \"Error: no test specified\" && exit 1"
|
package/readme.md
CHANGED
|
@@ -24,6 +24,9 @@ $ pnpm add rsult
|
|
|
24
24
|
|
|
25
25
|
```typescript
|
|
26
26
|
import { Option, Result, Some, None, Ok, Err } from 'rsult';
|
|
27
|
+
|
|
28
|
+
// Async variants for Promise-based workflows
|
|
29
|
+
import { ResultAsync, OptionAsync } from 'rsult';
|
|
27
30
|
```
|
|
28
31
|
|
|
29
32
|
### tl;dr
|
|
@@ -31,11 +34,8 @@ import { Option, Result, Some, None, Ok, Err } from 'rsult';
|
|
|
31
34
|
- rsult is inspired by Rust's `Option` and `Result` types.
|
|
32
35
|
- It helps you handle optional values and results, eliminating `null` and `undefined` checks.
|
|
33
36
|
- You can wrap values in `Some`, `None`, `Ok`, or `Err`, and use handy functions to transform, combine, and handle errors expressively.
|
|
34
|
-
-
|
|
35
|
-
|
|
36
|
-
### tl;dr
|
|
37
|
-
|
|
38
|
-
rsult makes your code safer and more predictable.
|
|
37
|
+
- Includes **async variants** (`ResultAsync`, `OptionAsync`) for seamless Promise-based workflows.
|
|
38
|
+
- Uses **branded types** for nominal typing and proper TypeScript type safety.
|
|
39
39
|
|
|
40
40
|
## Usage
|
|
41
41
|
|
|
@@ -109,6 +109,64 @@ const transformedResult = okResult.map(x => x * 2); // Ok(10)
|
|
|
109
109
|
const valueWithDefault = errResult.unwrap_or(0); // 0
|
|
110
110
|
```
|
|
111
111
|
|
|
112
|
+
### Async Variants
|
|
113
|
+
|
|
114
|
+
rsult provides `ResultAsync` and `OptionAsync` for working with Promises in a type-safe, composable way.
|
|
115
|
+
|
|
116
|
+
#### ResultAsync
|
|
117
|
+
|
|
118
|
+
```typescript
|
|
119
|
+
import { ResultAsync } from 'rsult';
|
|
120
|
+
|
|
121
|
+
// Create from various sources
|
|
122
|
+
const fromPromise = ResultAsync.fromPromise(fetch('/api/data'));
|
|
123
|
+
const fromTry = ResultAsync.try(async () => {
|
|
124
|
+
const response = await fetch('/api/data');
|
|
125
|
+
return response.json();
|
|
126
|
+
});
|
|
127
|
+
|
|
128
|
+
// Chain async operations
|
|
129
|
+
const result = await ResultAsync.ok(userId)
|
|
130
|
+
.andThen(id => fetchUser(id))
|
|
131
|
+
.map(user => user.name)
|
|
132
|
+
.mapErr(err => `Failed: ${err.message}`);
|
|
133
|
+
|
|
134
|
+
// Combine multiple async results
|
|
135
|
+
const combined = await ResultAsync.all([
|
|
136
|
+
fetchUser(1),
|
|
137
|
+
fetchUser(2),
|
|
138
|
+
fetchUser(3),
|
|
139
|
+
]);
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
#### OptionAsync
|
|
143
|
+
|
|
144
|
+
```typescript
|
|
145
|
+
import { OptionAsync } from 'rsult';
|
|
146
|
+
|
|
147
|
+
// Create from various sources
|
|
148
|
+
const fromNullable = OptionAsync.fromNullable(maybeValue);
|
|
149
|
+
const fromPromise = OptionAsync.fromPromise(fetchOptionalData());
|
|
150
|
+
|
|
151
|
+
// Chain async operations
|
|
152
|
+
const result = await OptionAsync.some(userId)
|
|
153
|
+
.andThen(id => findUser(id))
|
|
154
|
+
.map(user => user.email)
|
|
155
|
+
.filter(email => email.endsWith('@example.com'));
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
#### Converting Between Sync and Async
|
|
159
|
+
|
|
160
|
+
```typescript
|
|
161
|
+
// Sync to Async
|
|
162
|
+
const asyncResult = Ok(42).toAsync();
|
|
163
|
+
const asyncOption = Some('hello').toAsync();
|
|
164
|
+
|
|
165
|
+
// Async resolves to sync types
|
|
166
|
+
const syncResult: Result<number, Error> = await asyncResult;
|
|
167
|
+
const syncOption: Option<string> = await asyncOption;
|
|
168
|
+
```
|
|
169
|
+
|
|
112
170
|
## Advanced Usage
|
|
113
171
|
|
|
114
172
|
### Advanced Usage: Option
|
|
@@ -225,6 +283,7 @@ console.log(result); // "Parsed content: {"parsed":"Resource content"}"
|
|
|
225
283
|
- `is_some()`: Checks if the Option is Some.
|
|
226
284
|
- `is_none()`: Checks if the Option is None.
|
|
227
285
|
- `is_some_and(f: (arg: T) => boolean)`: Determines if the Option is Some and the contained value meets a condition.
|
|
286
|
+
- `is_none_or(f: (arg: T) => boolean)`: Returns `true` if the Option is None, or if Some and the value satisfies the predicate.
|
|
228
287
|
|
|
229
288
|
#### Transform Methods
|
|
230
289
|
- `map(fn: (arg: T) => U)`: Transforms the contained value of a Some with a provided function. Returns None if this Option is None.
|
|
@@ -259,6 +318,16 @@ console.log(result); // "Parsed content: {"parsed":"Resource content"}"
|
|
|
259
318
|
#### Flatten Method
|
|
260
319
|
- `flatten()`: Flattens a nested Option, if the Option contains another Option, returning the inner Option if it's Some.
|
|
261
320
|
|
|
321
|
+
#### Inspection Method
|
|
322
|
+
- `inspect(f: (arg: T) => void)`: Calls the provided function with the contained value if Some, returns the Option unchanged.
|
|
323
|
+
|
|
324
|
+
#### Conversion Methods
|
|
325
|
+
- `ok_or<E>(err: E)`: Transforms `Some(v)` to `Ok(v)` and `None` to `Err(err)`.
|
|
326
|
+
- `ok_or_else<E>(f: () => E)`: Transforms `Some(v)` to `Ok(v)` and `None` to `Err(f())`.
|
|
327
|
+
- `transpose()`: Transposes an `Option<Result<T, E>>` into a `Result<Option<T>, E>`.
|
|
328
|
+
- `unzip()`: Unzips an `Option<[A, B]>` into `[Option<A>, Option<B>]`.
|
|
329
|
+
- `toAsync()`: Converts the Option to an OptionAsync for async chaining.
|
|
330
|
+
|
|
262
331
|
### Result
|
|
263
332
|
|
|
264
333
|
#### Basic Methods
|
|
@@ -304,6 +373,93 @@ console.log(result); // "Parsed content: {"parsed":"Resource content"}"
|
|
|
304
373
|
- `iter()`: Returns an iterator over the potentially contained value.
|
|
305
374
|
- `flatten()`: Flattens a nested `Result` if the contained value is itself a `Result`.
|
|
306
375
|
|
|
376
|
+
#### Transpose and Conversion Methods
|
|
377
|
+
- `transpose()`: Transposes a `Result<Option<T>, E>` into an `Option<Result<T, E>>`.
|
|
378
|
+
- `toAsync()`: Converts the Result to a ResultAsync for async chaining.
|
|
379
|
+
|
|
380
|
+
### ResultAsync
|
|
381
|
+
|
|
382
|
+
A wrapper around `Promise<Result<T, E>>` that enables fluent async/await chains.
|
|
383
|
+
|
|
384
|
+
#### Constructors
|
|
385
|
+
- `ResultAsync.ok<T, E>(value: T)`: Creates a successful ResultAsync.
|
|
386
|
+
- `ResultAsync.err<T, E>(error: E)`: Creates a failed ResultAsync.
|
|
387
|
+
- `ResultAsync.fromResult(result: Result<T, E> | Promise<Result<T, E>>)`: Wraps a sync or async Result.
|
|
388
|
+
- `ResultAsync.fromPromise<T, E>(promise: Promise<T>, mapErr?: (e: unknown) => E)`: Converts a Promise to ResultAsync.
|
|
389
|
+
- `ResultAsync.try<T>(fn: () => T | Promise<T>)`: Executes a function and catches any errors.
|
|
390
|
+
|
|
391
|
+
#### Transformation Methods
|
|
392
|
+
- `map<U>(fn: (value: T) => U | Promise<U>)`: Transforms the Ok value.
|
|
393
|
+
- `mapErr<U>(fn: (error: E) => U | Promise<U>)`: Transforms the Err value.
|
|
394
|
+
- `mapOr<U>(defaultValue: U, fn: (value: T) => U | Promise<U>)`: Maps or returns default.
|
|
395
|
+
- `mapOrElse<U>(defaultFn: (error: E) => U, fn: (value: T) => U)`: Maps or computes default.
|
|
396
|
+
|
|
397
|
+
#### Chaining Methods
|
|
398
|
+
- `andThen<U>(fn: (value: T) => Result<U, E> | ResultAsync<U, E>)`: Chains on success.
|
|
399
|
+
- `orElse<U>(fn: (error: E) => Result<T, U> | ResultAsync<T, U>)`: Recovers from error.
|
|
400
|
+
- `and<U>(other: ResultAsync<U, E>)`: Returns other if Ok.
|
|
401
|
+
- `or<U>(other: ResultAsync<T, U>)`: Returns other if Err.
|
|
402
|
+
|
|
403
|
+
#### Unwrapping Methods
|
|
404
|
+
- `unwrap()`: Returns value or throws.
|
|
405
|
+
- `unwrapOr(defaultValue: T)`: Returns value or default.
|
|
406
|
+
- `unwrapOrElse(fn: (error: E) => T)`: Returns value or computes from error.
|
|
407
|
+
- `expect(message: string)`: Returns value or throws with message.
|
|
408
|
+
|
|
409
|
+
#### Inspection Methods
|
|
410
|
+
- `inspect(fn: (value: T) => void)`: Inspects Ok value.
|
|
411
|
+
- `inspectErr(fn: (error: E) => void)`: Inspects Err value.
|
|
412
|
+
- `isOk()`: Async check if Ok.
|
|
413
|
+
- `isErr()`: Async check if Err.
|
|
414
|
+
|
|
415
|
+
#### Static Combinators
|
|
416
|
+
- `ResultAsync.all<T, E>(results: ResultAsync<T, E>[])`: Combines all, short-circuits on first error.
|
|
417
|
+
- `ResultAsync.allSettled<T, E>(results: ResultAsync<T, E>[])`: Collects all errors.
|
|
418
|
+
|
|
419
|
+
#### Pattern Matching
|
|
420
|
+
- `match<U>({ Ok, Err })`: Pattern match with handlers.
|
|
421
|
+
|
|
422
|
+
### OptionAsync
|
|
423
|
+
|
|
424
|
+
A wrapper around `Promise<Option<T>>` that enables fluent async/await chains.
|
|
425
|
+
|
|
426
|
+
#### Constructors
|
|
427
|
+
- `OptionAsync.some<T>(value: T)`: Creates an OptionAsync with a value.
|
|
428
|
+
- `OptionAsync.none<T>()`: Creates an empty OptionAsync.
|
|
429
|
+
- `OptionAsync.fromOption(option: Option<T> | Promise<Option<T>>)`: Wraps a sync or async Option.
|
|
430
|
+
- `OptionAsync.fromPromise<T>(promise: Promise<T>)`: Converts resolved to Some, rejected to None.
|
|
431
|
+
- `OptionAsync.fromNullable<T>(value: T | null | undefined)`: Creates from nullable value.
|
|
432
|
+
- `OptionAsync.try<T>(fn: () => T | Promise<T>)`: Executes and returns Some on success, None on error.
|
|
433
|
+
|
|
434
|
+
#### Transformation Methods
|
|
435
|
+
- `map<U>(fn: (value: T) => U | Promise<U>)`: Transforms the Some value.
|
|
436
|
+
- `mapOr<U>(defaultValue: U, fn: (value: T) => U | Promise<U>)`: Maps or returns default.
|
|
437
|
+
- `mapOrElse<U>(defaultFn: () => U, fn: (value: T) => U)`: Maps or computes default.
|
|
438
|
+
- `filter(predicate: (value: T) => boolean | Promise<boolean>)`: Filters the Option.
|
|
439
|
+
|
|
440
|
+
#### Chaining Methods
|
|
441
|
+
- `andThen<U>(fn: (value: T) => Option<U> | OptionAsync<U>)`: Chains on Some.
|
|
442
|
+
- `orElse<U>(fn: () => Option<T> | OptionAsync<T>)`: Provides fallback on None.
|
|
443
|
+
- `and<U>(other: OptionAsync<U>)`: Returns other if Some.
|
|
444
|
+
- `or(other: OptionAsync<T>)`: Returns other if None.
|
|
445
|
+
|
|
446
|
+
#### Unwrapping Methods
|
|
447
|
+
- `unwrap()`: Returns value or throws.
|
|
448
|
+
- `unwrapOr(defaultValue: T)`: Returns value or default.
|
|
449
|
+
- `unwrapOrElse(fn: () => T)`: Returns value or computes default.
|
|
450
|
+
- `expect(message: string)`: Returns value or throws with message.
|
|
451
|
+
|
|
452
|
+
#### Conversion Methods
|
|
453
|
+
- `flatten()`: Flattens nested Option.
|
|
454
|
+
- `zip<U>(other: OptionAsync<U>)`: Combines two Options into tuple.
|
|
455
|
+
- `zipWith<U, R>(other: OptionAsync<U>, fn: (a: T, b: U) => R)`: Combines with function.
|
|
456
|
+
|
|
457
|
+
#### Static Combinators
|
|
458
|
+
- `OptionAsync.all<T>(options: OptionAsync<T>[])`: Combines all, returns None if any is None.
|
|
459
|
+
|
|
460
|
+
#### Pattern Matching
|
|
461
|
+
- `match<U>({ Some, None })`: Pattern match with handlers.
|
|
462
|
+
|
|
307
463
|
## Contributing
|
|
308
464
|
|
|
309
465
|
Contributions are welcome! Please open an issue or submit a pull request.
|