@shirudo/result 0.0.1
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/README.md +269 -0
- package/dist/index.cjs +1563 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +1033 -0
- package/dist/index.d.cts.map +1 -0
- package/dist/index.d.mts +1033 -0
- package/dist/index.d.mts.map +1 -0
- package/dist/index.mjs +1499 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +57 -0
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,1499 @@
|
|
|
1
|
+
//#region src/pipeable.ts
|
|
2
|
+
var Pipeable = class {
|
|
3
|
+
pipe(...ops) {
|
|
4
|
+
let ret = this;
|
|
5
|
+
for (const op of ops) ret = op(ret);
|
|
6
|
+
return ret;
|
|
7
|
+
}
|
|
8
|
+
async pipeAsync(...ops) {
|
|
9
|
+
let ret = this;
|
|
10
|
+
for (const op of ops) ret = await op(ret);
|
|
11
|
+
return ret;
|
|
12
|
+
}
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
//#endregion
|
|
16
|
+
//#region src/utils/isResult.ts
|
|
17
|
+
function isResult(value) {
|
|
18
|
+
return typeof value === "object" && value !== null && "isOk" in value && typeof value.isOk === "function" && "isErr" in value && typeof value.isErr === "function";
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
//#endregion
|
|
22
|
+
//#region src/matcher.ts
|
|
23
|
+
/**
|
|
24
|
+
* Matcher for Err values (returns any return type, e.g. string messages).
|
|
25
|
+
*
|
|
26
|
+
* - `.when(Ctor, handler)` matched via `instanceof`
|
|
27
|
+
* - `.whenGuard(guard, handler)` matched via type guard
|
|
28
|
+
* - `.run()` is only allowed once all error cases are handled (`E` is reduced to `never`)
|
|
29
|
+
*/
|
|
30
|
+
var ErrorMatchBuilder = class ErrorMatchBuilder {
|
|
31
|
+
#error;
|
|
32
|
+
#matched;
|
|
33
|
+
#value;
|
|
34
|
+
constructor(error, matched = false, value) {
|
|
35
|
+
this.#error = error;
|
|
36
|
+
this.#matched = matched;
|
|
37
|
+
this.#value = value;
|
|
38
|
+
Object.freeze(this);
|
|
39
|
+
}
|
|
40
|
+
when(ctor, handler) {
|
|
41
|
+
if (this.#matched) return this;
|
|
42
|
+
if (this.#error instanceof ctor) return new ErrorMatchBuilder(this.#error, true, handler(this.#error));
|
|
43
|
+
return this;
|
|
44
|
+
}
|
|
45
|
+
whenGuard(guard, handler) {
|
|
46
|
+
if (this.#matched) return this;
|
|
47
|
+
const error = this.#error;
|
|
48
|
+
if (guard(error)) return new ErrorMatchBuilder(this.#error, true, handler(error));
|
|
49
|
+
return this;
|
|
50
|
+
}
|
|
51
|
+
otherwise(handler) {
|
|
52
|
+
if (this.#matched) return this.#value;
|
|
53
|
+
return handler(this.#error);
|
|
54
|
+
}
|
|
55
|
+
run() {
|
|
56
|
+
if (this.#matched) return this.#value;
|
|
57
|
+
throw this.#error;
|
|
58
|
+
}
|
|
59
|
+
};
|
|
60
|
+
/**
|
|
61
|
+
* Matcher for `Result` errors that always returns a `Result`.
|
|
62
|
+
*
|
|
63
|
+
* Handlers may:
|
|
64
|
+
* - return a `Result` (returned directly)
|
|
65
|
+
* - return an error value (automatically wrapped to `Err(error)`)
|
|
66
|
+
*/
|
|
67
|
+
var ErrMatchBuilder = class ErrMatchBuilder {
|
|
68
|
+
#makeErr;
|
|
69
|
+
#error;
|
|
70
|
+
#resolved;
|
|
71
|
+
constructor(makeErr, error, resolved) {
|
|
72
|
+
this.#makeErr = makeErr;
|
|
73
|
+
this.#error = error;
|
|
74
|
+
this.#resolved = resolved;
|
|
75
|
+
Object.freeze(this);
|
|
76
|
+
}
|
|
77
|
+
static fromResult(result, makeErr) {
|
|
78
|
+
if (result.isOk()) return new ErrMatchBuilder(makeErr, void 0, result);
|
|
79
|
+
if (result.isErr()) return new ErrMatchBuilder(makeErr, result.error);
|
|
80
|
+
throw new Error("Unreachable: Result is neither Ok nor Err");
|
|
81
|
+
}
|
|
82
|
+
when(ctor, handler) {
|
|
83
|
+
if (this.#resolved) return this;
|
|
84
|
+
if (this.#error instanceof ctor) {
|
|
85
|
+
const out = handler(this.#error);
|
|
86
|
+
const resolved = isResult(out) ? out : this.#makeErr(out);
|
|
87
|
+
return new ErrMatchBuilder(this.#makeErr, this.#error, resolved);
|
|
88
|
+
}
|
|
89
|
+
return this;
|
|
90
|
+
}
|
|
91
|
+
whenGuard(guard, handler) {
|
|
92
|
+
if (this.#resolved) return this;
|
|
93
|
+
const error = this.#error;
|
|
94
|
+
if (guard(error)) {
|
|
95
|
+
const out = handler(error);
|
|
96
|
+
const resolved = isResult(out) ? out : this.#makeErr(out);
|
|
97
|
+
return new ErrMatchBuilder(this.#makeErr, this.#error, resolved);
|
|
98
|
+
}
|
|
99
|
+
return this;
|
|
100
|
+
}
|
|
101
|
+
otherwise(handler) {
|
|
102
|
+
if (this.#resolved) return this.#resolved;
|
|
103
|
+
const out = handler(this.#error);
|
|
104
|
+
return isResult(out) ? out : this.#makeErr(out);
|
|
105
|
+
}
|
|
106
|
+
run() {
|
|
107
|
+
if (this.#resolved) return this.#resolved;
|
|
108
|
+
throw this.#error;
|
|
109
|
+
}
|
|
110
|
+
};
|
|
111
|
+
/**
|
|
112
|
+
* Universal matcher for `Result` (Ok + Err in a single chain).
|
|
113
|
+
*
|
|
114
|
+
* - `.err(Ctor, handler)` matched via `instanceof`
|
|
115
|
+
* - `.errVal(value, handler)` matched via `Object.is`
|
|
116
|
+
* - `.ok(handler)` defines the success branch
|
|
117
|
+
* - `.run()` is only allowed after `.ok()` is set
|
|
118
|
+
*
|
|
119
|
+
* Lazy: if the Result is `Ok`, Err cases are not evaluated in `.run()`.
|
|
120
|
+
*/
|
|
121
|
+
var ResultMatchBuilder = class ResultMatchBuilder {
|
|
122
|
+
#result;
|
|
123
|
+
#errCases;
|
|
124
|
+
#okHandler;
|
|
125
|
+
constructor(result, errCases = [], okHandler) {
|
|
126
|
+
this.#result = result;
|
|
127
|
+
this.#errCases = Object.freeze([...errCases]);
|
|
128
|
+
this.#okHandler = okHandler;
|
|
129
|
+
Object.freeze(this);
|
|
130
|
+
}
|
|
131
|
+
static fromResult(result) {
|
|
132
|
+
return new ResultMatchBuilder(result);
|
|
133
|
+
}
|
|
134
|
+
err(ctor, handler) {
|
|
135
|
+
return new ResultMatchBuilder(this.#result, [...this.#errCases, {
|
|
136
|
+
kind: "ctor",
|
|
137
|
+
ctor,
|
|
138
|
+
handler
|
|
139
|
+
}], this.#okHandler);
|
|
140
|
+
}
|
|
141
|
+
errVal(value, handler) {
|
|
142
|
+
return new ResultMatchBuilder(this.#result, [...this.#errCases, {
|
|
143
|
+
kind: "val",
|
|
144
|
+
value,
|
|
145
|
+
handler
|
|
146
|
+
}], this.#okHandler);
|
|
147
|
+
}
|
|
148
|
+
ok(handler) {
|
|
149
|
+
return new ResultMatchBuilder(this.#result, this.#errCases, handler);
|
|
150
|
+
}
|
|
151
|
+
run() {
|
|
152
|
+
const result = this.#result;
|
|
153
|
+
if (result.isOk()) {
|
|
154
|
+
const okHandler = this.#okHandler;
|
|
155
|
+
if (!okHandler) throw new Error("ResultMatchBuilder.run() requires an ok() handler.");
|
|
156
|
+
return okHandler(result.value);
|
|
157
|
+
}
|
|
158
|
+
if (result.isErr()) {
|
|
159
|
+
const error = result.error;
|
|
160
|
+
for (const c of this.#errCases) {
|
|
161
|
+
if (c.kind === "ctor") {
|
|
162
|
+
if (error instanceof c.ctor) return c.handler(error);
|
|
163
|
+
continue;
|
|
164
|
+
}
|
|
165
|
+
if (Object.is(error, c.value)) return c.handler(error);
|
|
166
|
+
}
|
|
167
|
+
throw error;
|
|
168
|
+
}
|
|
169
|
+
throw new Error("Unreachable: Result is neither Ok nor Err");
|
|
170
|
+
}
|
|
171
|
+
};
|
|
172
|
+
|
|
173
|
+
//#endregion
|
|
174
|
+
//#region src/conversions/fromNullable.ts
|
|
175
|
+
/**
|
|
176
|
+
* Converts `null | undefined` to `Err`, everything else to `Ok`.
|
|
177
|
+
*
|
|
178
|
+
* **Type Safety**: The type assertion `as NonNullable<T>` is safe,
|
|
179
|
+
* as the runtime check guarantees that the value is not null/undefined.
|
|
180
|
+
*
|
|
181
|
+
* @param value The value to check
|
|
182
|
+
* @param error The error to use if value is null/undefined
|
|
183
|
+
* @returns An Ok Result with the NonNullable value, or an Err Result with the error
|
|
184
|
+
*
|
|
185
|
+
* @example
|
|
186
|
+
* ```ts
|
|
187
|
+
* fromNullable(user, 'User not found')
|
|
188
|
+
* // Ok(user) or Err('User not found')
|
|
189
|
+
* ```
|
|
190
|
+
*/
|
|
191
|
+
function fromNullable(value, error) {
|
|
192
|
+
if (value === null || value === void 0) return Result.err(error);
|
|
193
|
+
return Result.ok(value);
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
//#endregion
|
|
197
|
+
//#region src/conversions/fromPromise.ts
|
|
198
|
+
async function fromPromise(promise, errorMapper) {
|
|
199
|
+
try {
|
|
200
|
+
const value = await promise;
|
|
201
|
+
return Result.ok(value);
|
|
202
|
+
} catch (error) {
|
|
203
|
+
try {
|
|
204
|
+
return Result.err(errorMapper ? errorMapper(error) : error);
|
|
205
|
+
} catch (mapperError) {
|
|
206
|
+
return Result.err(mapperError);
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
//#endregion
|
|
212
|
+
//#region src/conversions/try.ts
|
|
213
|
+
/**
|
|
214
|
+
* Executes a function and catches exceptions.
|
|
215
|
+
*
|
|
216
|
+
* @param fn The function to execute
|
|
217
|
+
* @returns An Ok Result with the return value, or an Err Result with the caught exception
|
|
218
|
+
*
|
|
219
|
+
* @example
|
|
220
|
+
* ```ts
|
|
221
|
+
* const result = tryFn(() => JSON.parse(input));
|
|
222
|
+
* // Ok(parsed) or Err(SyntaxError)
|
|
223
|
+
* ```
|
|
224
|
+
*/
|
|
225
|
+
function tryFn(fn) {
|
|
226
|
+
try {
|
|
227
|
+
return Result.ok(fn());
|
|
228
|
+
} catch (error) {
|
|
229
|
+
return Result.err(error);
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
//#endregion
|
|
234
|
+
//#region src/conversions/toPromise.ts
|
|
235
|
+
/**
|
|
236
|
+
* Converts a Result to a Promise.
|
|
237
|
+
* Ok → resolves with the value, Err → rejects with the error
|
|
238
|
+
*
|
|
239
|
+
* @param result The Result to convert
|
|
240
|
+
* @returns A Promise that resolves with the value if Ok, or rejects with the error if Err
|
|
241
|
+
*
|
|
242
|
+
* @example
|
|
243
|
+
* ```ts
|
|
244
|
+
* const result = ok(42);
|
|
245
|
+
* const promise = toPromise(result);
|
|
246
|
+
* const value = await promise; // 42
|
|
247
|
+
* ```
|
|
248
|
+
*/
|
|
249
|
+
function toPromise(result) {
|
|
250
|
+
if (result.isOk()) return Promise.resolve(result.value);
|
|
251
|
+
return Promise.reject(result.error);
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
//#endregion
|
|
255
|
+
//#region src/conversions/toNullable.ts
|
|
256
|
+
/**
|
|
257
|
+
* Converts a Result to `T | null`.
|
|
258
|
+
* Ok → returns the value, Err → returns null
|
|
259
|
+
*
|
|
260
|
+
* @param result The Result to convert
|
|
261
|
+
* @returns The value if Ok, or null if Err
|
|
262
|
+
*
|
|
263
|
+
* @example
|
|
264
|
+
* ```ts
|
|
265
|
+
* const result = ok(42);
|
|
266
|
+
* const value = toNullable(result); // 42
|
|
267
|
+
*
|
|
268
|
+
* const errResult = err('error');
|
|
269
|
+
* const nullValue = toNullable(errResult); // null
|
|
270
|
+
* ```
|
|
271
|
+
*/
|
|
272
|
+
function toNullable(result) {
|
|
273
|
+
if (result.isOk()) return result.value;
|
|
274
|
+
return null;
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
//#endregion
|
|
278
|
+
//#region src/result.ts
|
|
279
|
+
var Result = class Result extends Pipeable {
|
|
280
|
+
#state;
|
|
281
|
+
constructor(state) {
|
|
282
|
+
super();
|
|
283
|
+
Object.freeze(state);
|
|
284
|
+
this.#state = state;
|
|
285
|
+
Object.freeze(this);
|
|
286
|
+
}
|
|
287
|
+
/**
|
|
288
|
+
* Creates an Ok Result with the given value.
|
|
289
|
+
*
|
|
290
|
+
* **Note**: `null` and `undefined` are allowed as values.
|
|
291
|
+
* If you want to convert `null`/`undefined` to an Err, use `fromNullable()`.
|
|
292
|
+
*
|
|
293
|
+
* @param value The value for the Ok Result
|
|
294
|
+
* @returns An Ok Result with the given value
|
|
295
|
+
*
|
|
296
|
+
* @example
|
|
297
|
+
* ```ts
|
|
298
|
+
* const result = Result.ok(42);
|
|
299
|
+
* const nullResult = Result.ok(null); // Allowed!
|
|
300
|
+
* ```
|
|
301
|
+
*/
|
|
302
|
+
static ok(value) {
|
|
303
|
+
return new Result({
|
|
304
|
+
_tag: "Ok",
|
|
305
|
+
value
|
|
306
|
+
});
|
|
307
|
+
}
|
|
308
|
+
/**
|
|
309
|
+
* Creates an Err Result with the given error.
|
|
310
|
+
*
|
|
311
|
+
* **Note**: `null` and `undefined` are allowed as errors.
|
|
312
|
+
*
|
|
313
|
+
* @param error The error for the Err Result
|
|
314
|
+
* @returns An Err Result with the given error
|
|
315
|
+
*
|
|
316
|
+
* @example
|
|
317
|
+
* ```ts
|
|
318
|
+
* const result = Result.err('error message');
|
|
319
|
+
* const nullError = Result.err(null); // Allowed!
|
|
320
|
+
* ```
|
|
321
|
+
*/
|
|
322
|
+
static err(error) {
|
|
323
|
+
return new Result({
|
|
324
|
+
_tag: "Err",
|
|
325
|
+
error
|
|
326
|
+
});
|
|
327
|
+
}
|
|
328
|
+
/**
|
|
329
|
+
* Converts `null | undefined` to `Err`, everything else to `Ok`.
|
|
330
|
+
*
|
|
331
|
+
* **Type Safety**: The type assertion `as NonNullable<T>` is safe,
|
|
332
|
+
* as the runtime check guarantees that the value is not null/undefined.
|
|
333
|
+
*
|
|
334
|
+
* @param value The value to check
|
|
335
|
+
* @param error The error to use if value is null/undefined
|
|
336
|
+
* @returns An Ok Result with the NonNullable value, or an Err Result with the error
|
|
337
|
+
*
|
|
338
|
+
* @example
|
|
339
|
+
* ```ts
|
|
340
|
+
* Result.fromNullable(user, 'User not found')
|
|
341
|
+
* // Ok(user) or Err('User not found')
|
|
342
|
+
* ```
|
|
343
|
+
*/
|
|
344
|
+
static fromNullable(value, error) {
|
|
345
|
+
return fromNullable(value, error);
|
|
346
|
+
}
|
|
347
|
+
static fromPromise(promise, errorMapper) {
|
|
348
|
+
return fromPromise(promise, errorMapper);
|
|
349
|
+
}
|
|
350
|
+
/**
|
|
351
|
+
* Executes a function and catches exceptions.
|
|
352
|
+
*
|
|
353
|
+
* @example
|
|
354
|
+
* ```ts
|
|
355
|
+
* const result = Result.try(() => JSON.parse(input));
|
|
356
|
+
* // Ok(parsed) or Err(SyntaxError)
|
|
357
|
+
* ```
|
|
358
|
+
*/
|
|
359
|
+
static try(fn) {
|
|
360
|
+
return tryFn(fn);
|
|
361
|
+
}
|
|
362
|
+
/**
|
|
363
|
+
* Checks if the Result is Ok.
|
|
364
|
+
*
|
|
365
|
+
* @returns `true` if the Result is Ok (and narrows the type)
|
|
366
|
+
*
|
|
367
|
+
* @example
|
|
368
|
+
* ```ts
|
|
369
|
+
* if (result.isOk()) {
|
|
370
|
+
* const value: T = result.value; // TypeScript knows that value is defined
|
|
371
|
+
* }
|
|
372
|
+
* ```
|
|
373
|
+
*/
|
|
374
|
+
isOk() {
|
|
375
|
+
return this.#state._tag === "Ok";
|
|
376
|
+
}
|
|
377
|
+
/**
|
|
378
|
+
* Checks if the Result is Err.
|
|
379
|
+
*
|
|
380
|
+
* @returns `true` if the Result is Err (and narrows the type)
|
|
381
|
+
*
|
|
382
|
+
* @example
|
|
383
|
+
* ```ts
|
|
384
|
+
* if (result.isErr()) {
|
|
385
|
+
* const error: E = result.error; // TypeScript knows that error is defined
|
|
386
|
+
* }
|
|
387
|
+
* ```
|
|
388
|
+
*/
|
|
389
|
+
isErr() {
|
|
390
|
+
return this.#state._tag === "Err";
|
|
391
|
+
}
|
|
392
|
+
get value() {
|
|
393
|
+
return this.#state._tag === "Ok" ? this.#state.value : void 0;
|
|
394
|
+
}
|
|
395
|
+
get error() {
|
|
396
|
+
return this.#state._tag === "Err" ? this.#state.error : void 0;
|
|
397
|
+
}
|
|
398
|
+
/**
|
|
399
|
+
* Returns the value, guaranteed to be defined after `isOk()` check.
|
|
400
|
+
* This method provides better type narrowing than the `value` getter.
|
|
401
|
+
*
|
|
402
|
+
* ⚠️ **Warning**: This method throws an Error if called on an Err result.
|
|
403
|
+
* Use this method only after a type guard (`if (result.isOk())`).
|
|
404
|
+
* For a safer alternative with a custom message, use `expect()`.
|
|
405
|
+
*
|
|
406
|
+
* @throws {Error} If called on an Err result
|
|
407
|
+
*
|
|
408
|
+
* @example
|
|
409
|
+
* ```ts
|
|
410
|
+
* if (result.isOk()) {
|
|
411
|
+
* const value = result.unwrap(); // Type is T, not T | undefined
|
|
412
|
+
* }
|
|
413
|
+
* ```
|
|
414
|
+
*/
|
|
415
|
+
unwrap() {
|
|
416
|
+
if (this.#state._tag === "Ok") return this.#state.value;
|
|
417
|
+
const errorStr = (() => {
|
|
418
|
+
try {
|
|
419
|
+
const error = this.#state.error;
|
|
420
|
+
if (error === null) return "null";
|
|
421
|
+
if (error === void 0) return "undefined";
|
|
422
|
+
if (typeof error === "string") return error;
|
|
423
|
+
if (error instanceof Error) return error.message;
|
|
424
|
+
if (typeof error === "object" && "toString" in error) try {
|
|
425
|
+
return String(error);
|
|
426
|
+
} catch {
|
|
427
|
+
return "[unstringifiable error]";
|
|
428
|
+
}
|
|
429
|
+
return String(error);
|
|
430
|
+
} catch {
|
|
431
|
+
return "[unstringifiable error]";
|
|
432
|
+
}
|
|
433
|
+
})();
|
|
434
|
+
throw new Error(`Called unwrap() on Err: ${errorStr}`);
|
|
435
|
+
}
|
|
436
|
+
/**
|
|
437
|
+
* Returns the error, guaranteed to be defined after `isErr()` check.
|
|
438
|
+
* This method provides better type narrowing than the `error` getter.
|
|
439
|
+
*
|
|
440
|
+
* ⚠️ **Warning**: This method throws an Error if called on an Ok result.
|
|
441
|
+
* Use this method only after a type guard (`if (result.isErr())`).
|
|
442
|
+
* For a safer alternative with a custom message, use `expectErr()`.
|
|
443
|
+
*
|
|
444
|
+
* @throws {Error} If called on an Ok result
|
|
445
|
+
*
|
|
446
|
+
* @example
|
|
447
|
+
* ```ts
|
|
448
|
+
* if (result.isErr()) {
|
|
449
|
+
* const error = result.unwrapErr(); // Type is E, not E | undefined
|
|
450
|
+
* }
|
|
451
|
+
* ```
|
|
452
|
+
*/
|
|
453
|
+
unwrapErr() {
|
|
454
|
+
if (this.#state._tag === "Err") return this.#state.error;
|
|
455
|
+
const valueStr = (() => {
|
|
456
|
+
try {
|
|
457
|
+
const value = this.#state.value;
|
|
458
|
+
if (value === null) return "null";
|
|
459
|
+
if (value === void 0) return "undefined";
|
|
460
|
+
if (typeof value === "string") return value;
|
|
461
|
+
if (value instanceof Error) return value.message;
|
|
462
|
+
if (typeof value === "object" && "toString" in value) try {
|
|
463
|
+
return String(value);
|
|
464
|
+
} catch {
|
|
465
|
+
return "[unstringifiable value]";
|
|
466
|
+
}
|
|
467
|
+
return String(value);
|
|
468
|
+
} catch {
|
|
469
|
+
return "[unstringifiable value]";
|
|
470
|
+
}
|
|
471
|
+
})();
|
|
472
|
+
throw new Error(`Called unwrapErr() on Ok: ${valueStr}`);
|
|
473
|
+
}
|
|
474
|
+
/**
|
|
475
|
+
* Returns the value with a custom error message if the result is Err.
|
|
476
|
+
* Similar to `unwrap()`, but allows you to provide a custom error message.
|
|
477
|
+
*
|
|
478
|
+
* ⚠️ **Warning**: This method throws an Error if called on an Err result.
|
|
479
|
+
* Use this method only if you are sure the Result is Ok,
|
|
480
|
+
* or if you need a meaningful error message.
|
|
481
|
+
*
|
|
482
|
+
* @param message Custom error message to throw if result is Err
|
|
483
|
+
* @returns The value if result is Ok
|
|
484
|
+
* @throws {Error} If called on an Err result with the provided message
|
|
485
|
+
*
|
|
486
|
+
* @example
|
|
487
|
+
* ```ts
|
|
488
|
+
* const result = fetchUser(id);
|
|
489
|
+
* const user = result.expect('User should exist'); // Throws with custom message if Err
|
|
490
|
+
* ```
|
|
491
|
+
*/
|
|
492
|
+
expect(message) {
|
|
493
|
+
if (this.#state._tag === "Ok") return this.#state.value;
|
|
494
|
+
throw new Error(message);
|
|
495
|
+
}
|
|
496
|
+
/**
|
|
497
|
+
* Returns the error with a custom error message if the result is Ok.
|
|
498
|
+
* Similar to `unwrapErr()`, but allows you to provide a custom error message.
|
|
499
|
+
*
|
|
500
|
+
* ⚠️ **Warning**: This method throws an Error if called on an Ok result.
|
|
501
|
+
* Use this method only if you are sure the Result is Err,
|
|
502
|
+
* or if you need a meaningful error message.
|
|
503
|
+
*
|
|
504
|
+
* @param message Custom error message to throw if result is Ok
|
|
505
|
+
* @returns The error if result is Err
|
|
506
|
+
* @throws {Error} If called on an Ok result with the provided message
|
|
507
|
+
*
|
|
508
|
+
* @example
|
|
509
|
+
* ```ts
|
|
510
|
+
* const result = validateInput(input);
|
|
511
|
+
* if (result.isErr()) {
|
|
512
|
+
* const error = result.expectErr('Validation should have failed'); // Throws if Ok
|
|
513
|
+
* }
|
|
514
|
+
* ```
|
|
515
|
+
*/
|
|
516
|
+
expectErr(message) {
|
|
517
|
+
if (this.#state._tag === "Err") return this.#state.error;
|
|
518
|
+
throw new Error(message);
|
|
519
|
+
}
|
|
520
|
+
unwrapOr(defaultValue) {
|
|
521
|
+
return this.#state._tag === "Ok" ? this.#state.value : defaultValue;
|
|
522
|
+
}
|
|
523
|
+
/**
|
|
524
|
+
* Converts the Result to a Promise.
|
|
525
|
+
* Ok → resolves with the value, Err → rejects with the error
|
|
526
|
+
*
|
|
527
|
+
* This instance method delegates to the standalone `toPromise()` function.
|
|
528
|
+
*
|
|
529
|
+
* @returns A Promise that resolves with the value if Ok, or rejects with the error if Err
|
|
530
|
+
*
|
|
531
|
+
* @example
|
|
532
|
+
* ```ts
|
|
533
|
+
* const result = ok(42);
|
|
534
|
+
* const promise = result.toPromise();
|
|
535
|
+
* const value = await promise; // 42
|
|
536
|
+
*
|
|
537
|
+
* const errResult = err('error');
|
|
538
|
+
* try {
|
|
539
|
+
* await errResult.toPromise();
|
|
540
|
+
* } catch (error) {
|
|
541
|
+
* console.log(error); // 'error'
|
|
542
|
+
* }
|
|
543
|
+
* ```
|
|
544
|
+
*/
|
|
545
|
+
toPromise() {
|
|
546
|
+
return toPromise(this);
|
|
547
|
+
}
|
|
548
|
+
/**
|
|
549
|
+
* Converts the Result to `T | null`.
|
|
550
|
+
* Ok → returns the value, Err → returns null
|
|
551
|
+
*
|
|
552
|
+
* This instance method delegates to the standalone `toNullable()` function.
|
|
553
|
+
*
|
|
554
|
+
* @returns The value if Ok, or null if Err
|
|
555
|
+
*
|
|
556
|
+
* @example
|
|
557
|
+
* ```ts
|
|
558
|
+
* const result = ok(42);
|
|
559
|
+
* const value = result.toNullable(); // 42
|
|
560
|
+
*
|
|
561
|
+
* const errResult = err('error');
|
|
562
|
+
* const nullValue = errResult.toNullable(); // null
|
|
563
|
+
* ```
|
|
564
|
+
*/
|
|
565
|
+
toNullable() {
|
|
566
|
+
return toNullable(this);
|
|
567
|
+
}
|
|
568
|
+
/**
|
|
569
|
+
* Enables `yield* result` in generators (Do-notation).
|
|
570
|
+
*
|
|
571
|
+
* The iterator yields the `Result` itself; the runner (see `task`) decides:
|
|
572
|
+
* - Ok → sends back the Ok value (`next(value)`), `yield*` yields `T`
|
|
573
|
+
* - Err → aborts and returns the Err Result
|
|
574
|
+
*/
|
|
575
|
+
*[Symbol.iterator]() {
|
|
576
|
+
return yield this;
|
|
577
|
+
}
|
|
578
|
+
/**
|
|
579
|
+
* Universal pattern matcher for Ok + Err cases.
|
|
580
|
+
*
|
|
581
|
+
* Use this to exhaustively match on both success and error cases with type-based
|
|
582
|
+
* and value-based pattern matching.
|
|
583
|
+
*
|
|
584
|
+
* @example
|
|
585
|
+
* ```ts
|
|
586
|
+
* const message = result
|
|
587
|
+
* .match()
|
|
588
|
+
* .err(NetworkError, e => `Network: ${e.message}`)
|
|
589
|
+
* .err(ValidationError, e => `Validation: ${e.message}`)
|
|
590
|
+
* .ok(val => `Success: ${val}`)
|
|
591
|
+
* .run();
|
|
592
|
+
* ```
|
|
593
|
+
*/
|
|
594
|
+
match() {
|
|
595
|
+
return ResultMatchBuilder.fromResult(this);
|
|
596
|
+
}
|
|
597
|
+
matchErr() {
|
|
598
|
+
if (this.isErr()) return new ErrorMatchBuilder(this.error);
|
|
599
|
+
throw new Error("matchErr() can only be called on Err results. Use `if (result.isErr()) { ... }` first.");
|
|
600
|
+
}
|
|
601
|
+
/**
|
|
602
|
+
* Matches on the Err value, but normalizes every branch to a `Result`:
|
|
603
|
+
* - Handlers may return a `Result` (returned directly)
|
|
604
|
+
* - or an error value (wrapped to `Err(error)`)
|
|
605
|
+
*/
|
|
606
|
+
matchErrResult() {
|
|
607
|
+
const makeErr = (error) => Result.err(error);
|
|
608
|
+
return ErrMatchBuilder.fromResult(this, makeErr);
|
|
609
|
+
}
|
|
610
|
+
/**
|
|
611
|
+
* @deprecated Use `.match()` instead. Will be removed in next major version.
|
|
612
|
+
*/
|
|
613
|
+
pattern() {
|
|
614
|
+
return this.match();
|
|
615
|
+
}
|
|
616
|
+
/**
|
|
617
|
+
* @deprecated Use `.match()` instead. Will be removed in next major version.
|
|
618
|
+
*/
|
|
619
|
+
switch() {
|
|
620
|
+
return this.match();
|
|
621
|
+
}
|
|
622
|
+
/**
|
|
623
|
+
* Folds the Result into a single value by applying one of two functions.
|
|
624
|
+
*
|
|
625
|
+
* This is a direct method equivalent to the `match` pipe operator.
|
|
626
|
+
* Use this when you want to handle both Ok and Err cases and return a single value.
|
|
627
|
+
*
|
|
628
|
+
* @param onOk Function to apply if the Result is Ok
|
|
629
|
+
* @param onErr Function to apply if the Result is Err
|
|
630
|
+
* @returns The result of applying the appropriate function
|
|
631
|
+
*
|
|
632
|
+
* @example
|
|
633
|
+
* ```ts
|
|
634
|
+
* const result = ok(42);
|
|
635
|
+
* const message = result.fold(
|
|
636
|
+
* val => `Success: ${val}`,
|
|
637
|
+
* err => `Error: ${err}`
|
|
638
|
+
* );
|
|
639
|
+
* // message = "Success: 42"
|
|
640
|
+
* ```
|
|
641
|
+
*
|
|
642
|
+
* @example
|
|
643
|
+
* ```ts
|
|
644
|
+
* // Works with discriminated unions
|
|
645
|
+
* const result: Result<string, number> = err(404);
|
|
646
|
+
* const response = result.fold(
|
|
647
|
+
* data => ({ success: true as const, data }),
|
|
648
|
+
* code => ({ success: false as const, code })
|
|
649
|
+
* );
|
|
650
|
+
* // response: { success: true; data: string } | { success: false; code: number }
|
|
651
|
+
* ```
|
|
652
|
+
*/
|
|
653
|
+
fold(onOk, onErr) {
|
|
654
|
+
if (this.isOk()) return onOk(this.value);
|
|
655
|
+
if (this.isErr()) return onErr(this.error);
|
|
656
|
+
throw new Error("Unreachable: Result is neither Ok nor Err");
|
|
657
|
+
}
|
|
658
|
+
/**
|
|
659
|
+
* Returns the Result as a discriminated union (`{ _tag: 'Ok', value } | { _tag: 'Err', error }`).
|
|
660
|
+
* Useful for libraries like `ts-pattern` that match on plain object unions.
|
|
661
|
+
*/
|
|
662
|
+
toUnion() {
|
|
663
|
+
return this.#state;
|
|
664
|
+
}
|
|
665
|
+
/**
|
|
666
|
+
* Serializes the Result into a simple object format.
|
|
667
|
+
* Preserves the original types.
|
|
668
|
+
*/
|
|
669
|
+
serialize() {
|
|
670
|
+
if (this.#state._tag === "Ok") return {
|
|
671
|
+
isSuccess: true,
|
|
672
|
+
data: this.#state.value
|
|
673
|
+
};
|
|
674
|
+
return {
|
|
675
|
+
isSuccess: false,
|
|
676
|
+
error: this.#state.error
|
|
677
|
+
};
|
|
678
|
+
}
|
|
679
|
+
/**
|
|
680
|
+
* Serializes the Result into a user-friendly format.
|
|
681
|
+
* Converts errors to readable strings.
|
|
682
|
+
*/
|
|
683
|
+
toUserFriendly() {
|
|
684
|
+
if (this.#state._tag === "Ok") return {
|
|
685
|
+
isSuccess: true,
|
|
686
|
+
data: this.#state.value
|
|
687
|
+
};
|
|
688
|
+
const error = this.#state.error;
|
|
689
|
+
const toSafeString = (value) => {
|
|
690
|
+
try {
|
|
691
|
+
return String(value);
|
|
692
|
+
} catch {
|
|
693
|
+
return "[Unstringifiable error]";
|
|
694
|
+
}
|
|
695
|
+
};
|
|
696
|
+
return {
|
|
697
|
+
isSuccess: false,
|
|
698
|
+
error: (() => {
|
|
699
|
+
if (error && typeof error === "object" && "message" in error) {
|
|
700
|
+
const message = error.message;
|
|
701
|
+
return typeof message === "string" ? message : toSafeString(error);
|
|
702
|
+
}
|
|
703
|
+
return toSafeString(error);
|
|
704
|
+
})()
|
|
705
|
+
};
|
|
706
|
+
}
|
|
707
|
+
};
|
|
708
|
+
const ok = Result.ok;
|
|
709
|
+
const err = Result.err;
|
|
710
|
+
/**
|
|
711
|
+
* Helper for conditional Result creation.
|
|
712
|
+
* Avoids type inference issues with ternary operators.
|
|
713
|
+
*
|
|
714
|
+
* @example
|
|
715
|
+
* ```ts
|
|
716
|
+
* const result = okIf(value > 5, value, 'too small');
|
|
717
|
+
* // instead of: value > 5 ? ok(value) : err('too small')
|
|
718
|
+
* ```
|
|
719
|
+
*/
|
|
720
|
+
function okIf(condition, okValue, errValue) {
|
|
721
|
+
return condition ? ok(okValue) : err(errValue);
|
|
722
|
+
}
|
|
723
|
+
/**
|
|
724
|
+
* Helper for conditional Result creation with lazy evaluation.
|
|
725
|
+
* Evaluates values only when they are needed.
|
|
726
|
+
*
|
|
727
|
+
* @example
|
|
728
|
+
* ```ts
|
|
729
|
+
* const result = okIfLazy(
|
|
730
|
+
* value > 5,
|
|
731
|
+
* () => expensiveComputation(value),
|
|
732
|
+
* () => 'too small'
|
|
733
|
+
* );
|
|
734
|
+
* ```
|
|
735
|
+
*/
|
|
736
|
+
function okIfLazy(condition, okFn, errFn) {
|
|
737
|
+
return condition ? ok(okFn()) : err(errFn());
|
|
738
|
+
}
|
|
739
|
+
|
|
740
|
+
//#endregion
|
|
741
|
+
//#region src/gen.ts
|
|
742
|
+
async function task(makeGenerator, onThrow) {
|
|
743
|
+
const iterator = makeGenerator();
|
|
744
|
+
let input = void 0;
|
|
745
|
+
while (true) {
|
|
746
|
+
let step;
|
|
747
|
+
try {
|
|
748
|
+
step = await iterator.next(input);
|
|
749
|
+
} catch (caught) {
|
|
750
|
+
if (!onThrow) throw caught;
|
|
751
|
+
return err(onThrow(caught));
|
|
752
|
+
}
|
|
753
|
+
if (step.done) try {
|
|
754
|
+
const awaited = await step.value;
|
|
755
|
+
if (isResult(awaited)) return awaited;
|
|
756
|
+
return ok(awaited);
|
|
757
|
+
} catch (caught) {
|
|
758
|
+
if (!onThrow) throw caught;
|
|
759
|
+
return err(onThrow(caught));
|
|
760
|
+
}
|
|
761
|
+
const yielded = step.value;
|
|
762
|
+
if (!isResult(yielded)) throw new TypeError("task() expected yielded values to be Result. Use `yield*` on a Result.");
|
|
763
|
+
if (yielded.isOk()) {
|
|
764
|
+
input = yielded.value;
|
|
765
|
+
continue;
|
|
766
|
+
}
|
|
767
|
+
if (yielded.isErr()) {
|
|
768
|
+
try {
|
|
769
|
+
if (typeof iterator.return === "function") await iterator.return(void 0);
|
|
770
|
+
} catch (caught) {
|
|
771
|
+
if (!onThrow) throw caught;
|
|
772
|
+
return err(onThrow(caught));
|
|
773
|
+
}
|
|
774
|
+
return yielded;
|
|
775
|
+
}
|
|
776
|
+
throw new Error("Unreachable: Result is neither Ok nor Err");
|
|
777
|
+
}
|
|
778
|
+
}
|
|
779
|
+
const gen = task;
|
|
780
|
+
|
|
781
|
+
//#endregion
|
|
782
|
+
//#region src/operators/map.ts
|
|
783
|
+
/**
|
|
784
|
+
* Transforms the value (Ok case).
|
|
785
|
+
* Equivalent to Rust `map`.
|
|
786
|
+
*/
|
|
787
|
+
function map(project) {
|
|
788
|
+
return (source) => {
|
|
789
|
+
if (source.isOk()) return ok(project(source.value));
|
|
790
|
+
return source;
|
|
791
|
+
};
|
|
792
|
+
}
|
|
793
|
+
|
|
794
|
+
//#endregion
|
|
795
|
+
//#region src/operators/mapErr.ts
|
|
796
|
+
/**
|
|
797
|
+
* Transforms the error (Err case).
|
|
798
|
+
* Equivalent to Rust `map_err`.
|
|
799
|
+
*/
|
|
800
|
+
function mapErr(project) {
|
|
801
|
+
return (source) => {
|
|
802
|
+
if (source.isErr()) return err(project(source.error));
|
|
803
|
+
return source;
|
|
804
|
+
};
|
|
805
|
+
}
|
|
806
|
+
|
|
807
|
+
//#endregion
|
|
808
|
+
//#region src/operators/mapBoth.ts
|
|
809
|
+
/**
|
|
810
|
+
* Transforms both the Ok value and the Err error.
|
|
811
|
+
* Equivalent to FP `bimap` / `mapBoth`.
|
|
812
|
+
*/
|
|
813
|
+
function mapBoth(mapOk, mapErr$1) {
|
|
814
|
+
return (source) => {
|
|
815
|
+
if (source.isOk()) return ok(mapOk(source.value));
|
|
816
|
+
if (source.isErr()) return err(mapErr$1(source.error));
|
|
817
|
+
throw new Error("Unreachable: Result is neither Ok nor Err");
|
|
818
|
+
};
|
|
819
|
+
}
|
|
820
|
+
/**
|
|
821
|
+
* Alias for `mapBoth`.
|
|
822
|
+
*/
|
|
823
|
+
const bimap = mapBoth;
|
|
824
|
+
|
|
825
|
+
//#endregion
|
|
826
|
+
//#region src/operators/flatMap.ts
|
|
827
|
+
/**
|
|
828
|
+
* Chains another operation that returns a Result.
|
|
829
|
+
* Equivalent to Rust `and_then` or JS `flatMap`.
|
|
830
|
+
*/
|
|
831
|
+
function flatMap(project) {
|
|
832
|
+
return (source) => {
|
|
833
|
+
if (source.isOk()) return project(source.value);
|
|
834
|
+
return source;
|
|
835
|
+
};
|
|
836
|
+
}
|
|
837
|
+
|
|
838
|
+
//#endregion
|
|
839
|
+
//#region src/operators/tap.ts
|
|
840
|
+
/**
|
|
841
|
+
* Executes a side effect (logging, debugging) without changing the Result.
|
|
842
|
+
* Equivalent to Rust `inspect` / `inspect_err`.
|
|
843
|
+
*/
|
|
844
|
+
function tap(observer) {
|
|
845
|
+
return (source) => {
|
|
846
|
+
if (source.isOk() && observer.ok) observer.ok(source.value);
|
|
847
|
+
if (source.isErr() && observer.err) observer.err(source.error);
|
|
848
|
+
return source;
|
|
849
|
+
};
|
|
850
|
+
}
|
|
851
|
+
|
|
852
|
+
//#endregion
|
|
853
|
+
//#region src/operators/filter.ts
|
|
854
|
+
/**
|
|
855
|
+
* Checks a predicate. If false, the Result becomes Err.
|
|
856
|
+
* Partially equivalent to Rust `filter`.
|
|
857
|
+
*/
|
|
858
|
+
function filter(predicate, errorFn) {
|
|
859
|
+
return (source) => {
|
|
860
|
+
if (source.isOk()) {
|
|
861
|
+
if (predicate(source.value)) return source;
|
|
862
|
+
return err(errorFn());
|
|
863
|
+
}
|
|
864
|
+
return source;
|
|
865
|
+
};
|
|
866
|
+
}
|
|
867
|
+
|
|
868
|
+
//#endregion
|
|
869
|
+
//#region src/operators/fold.ts
|
|
870
|
+
/**
|
|
871
|
+
* Folds the Result into a single value by applying one of two functions.
|
|
872
|
+
* The end of the pipe.
|
|
873
|
+
*
|
|
874
|
+
* This is the pipe operator equivalent of the `.fold()` instance method.
|
|
875
|
+
*/
|
|
876
|
+
function fold(handlers) {
|
|
877
|
+
return (source) => {
|
|
878
|
+
if (source.isOk()) return handlers.ok(source.value);
|
|
879
|
+
if (source.isErr()) return handlers.err(source.error);
|
|
880
|
+
throw new Error("Unreachable: Result is neither Ok nor Err");
|
|
881
|
+
};
|
|
882
|
+
}
|
|
883
|
+
/**
|
|
884
|
+
* @deprecated Use `fold` instead. Will be removed in next major version.
|
|
885
|
+
*/
|
|
886
|
+
const match = fold;
|
|
887
|
+
|
|
888
|
+
//#endregion
|
|
889
|
+
//#region src/operators/tryCatch.ts
|
|
890
|
+
/**
|
|
891
|
+
* Executes a function and catches exceptions.
|
|
892
|
+
* Converts exceptions into Result<E>.
|
|
893
|
+
* Equivalent to Rust `Result::from` for fallible operations.
|
|
894
|
+
*/
|
|
895
|
+
function tryCatch(fn, errorMapper) {
|
|
896
|
+
return (source) => {
|
|
897
|
+
if (source.isErr()) return source;
|
|
898
|
+
try {
|
|
899
|
+
return ok(fn());
|
|
900
|
+
} catch (error) {
|
|
901
|
+
return err(errorMapper ? errorMapper(error) : error);
|
|
902
|
+
}
|
|
903
|
+
};
|
|
904
|
+
}
|
|
905
|
+
|
|
906
|
+
//#endregion
|
|
907
|
+
//#region src/operators/tryMap.ts
|
|
908
|
+
/**
|
|
909
|
+
* Like `map`, but catches exceptions and turns them into Err.
|
|
910
|
+
*/
|
|
911
|
+
function tryMap(project, errorMapper) {
|
|
912
|
+
return (source) => {
|
|
913
|
+
if (source.isErr()) return source;
|
|
914
|
+
try {
|
|
915
|
+
if (source.isOk()) return ok(project(source.value));
|
|
916
|
+
throw new Error("Unreachable: Result is neither Ok nor Err");
|
|
917
|
+
} catch (error) {
|
|
918
|
+
return err(errorMapper ? errorMapper(error) : error);
|
|
919
|
+
}
|
|
920
|
+
};
|
|
921
|
+
}
|
|
922
|
+
|
|
923
|
+
//#endregion
|
|
924
|
+
//#region src/operators/recover.ts
|
|
925
|
+
/**
|
|
926
|
+
* Recover: turns Err into Ok(defaultValue).
|
|
927
|
+
* Result is guaranteed Ok → error type becomes `never`.
|
|
928
|
+
*/
|
|
929
|
+
function recover(defaultValue) {
|
|
930
|
+
return (source) => {
|
|
931
|
+
if (source.isOk()) return source;
|
|
932
|
+
if (source.isErr()) return ok(defaultValue);
|
|
933
|
+
throw new Error("Unreachable: Result is neither Ok nor Err");
|
|
934
|
+
};
|
|
935
|
+
}
|
|
936
|
+
/**
|
|
937
|
+
* Like `recover`, but computes the default value from the error.
|
|
938
|
+
*/
|
|
939
|
+
function recoverWith(fn) {
|
|
940
|
+
return (source) => {
|
|
941
|
+
if (source.isOk()) return source;
|
|
942
|
+
if (source.isErr()) return ok(fn(source.error));
|
|
943
|
+
throw new Error("Unreachable: Result is neither Ok nor Err");
|
|
944
|
+
};
|
|
945
|
+
}
|
|
946
|
+
|
|
947
|
+
//#endregion
|
|
948
|
+
//#region src/operators-async/mapAsync.ts
|
|
949
|
+
/**
|
|
950
|
+
* Async version of map.
|
|
951
|
+
*/
|
|
952
|
+
function mapAsync(project) {
|
|
953
|
+
return async (source) => {
|
|
954
|
+
if (source.isOk()) return ok(await project(source.value));
|
|
955
|
+
return source;
|
|
956
|
+
};
|
|
957
|
+
}
|
|
958
|
+
|
|
959
|
+
//#endregion
|
|
960
|
+
//#region src/operators-async/mapErrAsync.ts
|
|
961
|
+
/**
|
|
962
|
+
* Async version of mapErr.
|
|
963
|
+
*/
|
|
964
|
+
function mapErrAsync(project) {
|
|
965
|
+
return async (source) => {
|
|
966
|
+
if (source.isErr()) return err(await project(source.error));
|
|
967
|
+
return source;
|
|
968
|
+
};
|
|
969
|
+
}
|
|
970
|
+
|
|
971
|
+
//#endregion
|
|
972
|
+
//#region src/operators-async/flatMapAsync.ts
|
|
973
|
+
/**
|
|
974
|
+
* Async version of flatMap.
|
|
975
|
+
* Allows different error types in the projected Result.
|
|
976
|
+
*/
|
|
977
|
+
function flatMapAsync(project) {
|
|
978
|
+
return async (source) => {
|
|
979
|
+
if (source.isOk()) return await project(source.value);
|
|
980
|
+
return source;
|
|
981
|
+
};
|
|
982
|
+
}
|
|
983
|
+
|
|
984
|
+
//#endregion
|
|
985
|
+
//#region src/operators-async/tapAsync.ts
|
|
986
|
+
/**
|
|
987
|
+
* Async version of tap.
|
|
988
|
+
*/
|
|
989
|
+
function tapAsync(observer) {
|
|
990
|
+
return async (source) => {
|
|
991
|
+
if (source.isOk() && observer.ok) await observer.ok(source.value);
|
|
992
|
+
if (source.isErr() && observer.err) await observer.err(source.error);
|
|
993
|
+
return source;
|
|
994
|
+
};
|
|
995
|
+
}
|
|
996
|
+
|
|
997
|
+
//#endregion
|
|
998
|
+
//#region src/operators-async/filterAsync.ts
|
|
999
|
+
/**
|
|
1000
|
+
* Async version of filter.
|
|
1001
|
+
*/
|
|
1002
|
+
function filterAsync(predicate, errorFn) {
|
|
1003
|
+
return async (source) => {
|
|
1004
|
+
if (source.isOk()) {
|
|
1005
|
+
if (await predicate(source.value)) return source;
|
|
1006
|
+
return err(await errorFn());
|
|
1007
|
+
}
|
|
1008
|
+
return source;
|
|
1009
|
+
};
|
|
1010
|
+
}
|
|
1011
|
+
|
|
1012
|
+
//#endregion
|
|
1013
|
+
//#region src/operators-async/foldAsync.ts
|
|
1014
|
+
/**
|
|
1015
|
+
* Async version of `fold`. Folds the Result into a single value asynchronously.
|
|
1016
|
+
* The end of the pipe.
|
|
1017
|
+
*
|
|
1018
|
+
* This is the async pipe operator equivalent of the `.fold()` instance method.
|
|
1019
|
+
*/
|
|
1020
|
+
function foldAsync(handlers) {
|
|
1021
|
+
return async (source) => {
|
|
1022
|
+
if (source.isOk()) return await handlers.ok(source.value);
|
|
1023
|
+
if (source.isErr()) return await handlers.err(source.error);
|
|
1024
|
+
throw new Error("Unreachable: Result is neither Ok nor Err");
|
|
1025
|
+
};
|
|
1026
|
+
}
|
|
1027
|
+
/**
|
|
1028
|
+
* @deprecated Use `foldAsync` instead. Will be removed in next major version.
|
|
1029
|
+
*/
|
|
1030
|
+
const matchAsync = foldAsync;
|
|
1031
|
+
|
|
1032
|
+
//#endregion
|
|
1033
|
+
//#region src/operators-async/tryCatchAsync.ts
|
|
1034
|
+
/**
|
|
1035
|
+
* Async version of tryCatch.
|
|
1036
|
+
*/
|
|
1037
|
+
function tryCatchAsync(fn, errorMapper) {
|
|
1038
|
+
return async (source) => {
|
|
1039
|
+
if (source.isErr()) return source;
|
|
1040
|
+
try {
|
|
1041
|
+
return ok(await fn());
|
|
1042
|
+
} catch (error) {
|
|
1043
|
+
return err(errorMapper ? errorMapper(error) : error);
|
|
1044
|
+
}
|
|
1045
|
+
};
|
|
1046
|
+
}
|
|
1047
|
+
|
|
1048
|
+
//#endregion
|
|
1049
|
+
//#region src/operators-async/tryMapAsync.ts
|
|
1050
|
+
/**
|
|
1051
|
+
* Async version of tryMap.
|
|
1052
|
+
*/
|
|
1053
|
+
function tryMapAsync(project, errorMapper) {
|
|
1054
|
+
return async (source) => {
|
|
1055
|
+
if (source.isErr()) return source;
|
|
1056
|
+
try {
|
|
1057
|
+
if (source.isOk()) return ok(await project(source.value));
|
|
1058
|
+
throw new Error("Unreachable: Result is neither Ok nor Err");
|
|
1059
|
+
} catch (error) {
|
|
1060
|
+
return err(errorMapper ? errorMapper(error) : error);
|
|
1061
|
+
}
|
|
1062
|
+
};
|
|
1063
|
+
}
|
|
1064
|
+
|
|
1065
|
+
//#endregion
|
|
1066
|
+
//#region src/unwrap/unwrap.ts
|
|
1067
|
+
/**
|
|
1068
|
+
* Returns the value or throws an Error.
|
|
1069
|
+
* Equivalent to Rust `unwrap`.
|
|
1070
|
+
*/
|
|
1071
|
+
function unwrap(result) {
|
|
1072
|
+
if (result.isOk()) return result.value;
|
|
1073
|
+
if (result.isErr()) throw new Error(`Called unwrap() on Err: ${String(result.error)}`);
|
|
1074
|
+
throw new Error("Unreachable: Result is neither Ok nor Err");
|
|
1075
|
+
}
|
|
1076
|
+
|
|
1077
|
+
//#endregion
|
|
1078
|
+
//#region src/unwrap/unwrapOr.ts
|
|
1079
|
+
/**
|
|
1080
|
+
* Returns the value or a default value.
|
|
1081
|
+
* Pure function alternative to the instance method.
|
|
1082
|
+
*/
|
|
1083
|
+
function unwrapOr(result, defaultValue) {
|
|
1084
|
+
if (result.isOk()) return result.value;
|
|
1085
|
+
return defaultValue;
|
|
1086
|
+
}
|
|
1087
|
+
|
|
1088
|
+
//#endregion
|
|
1089
|
+
//#region src/unwrap/unwrapOrElse.ts
|
|
1090
|
+
/**
|
|
1091
|
+
* Returns the value or computes a default value with a function.
|
|
1092
|
+
* Equivalent to Rust `unwrap_or_else`.
|
|
1093
|
+
*/
|
|
1094
|
+
function unwrapOrElse(result, fn) {
|
|
1095
|
+
if (result.isOk()) return result.value;
|
|
1096
|
+
if (result.isErr()) return fn(result.error);
|
|
1097
|
+
throw new Error("Unreachable: Result is neither Ok nor Err");
|
|
1098
|
+
}
|
|
1099
|
+
|
|
1100
|
+
//#endregion
|
|
1101
|
+
//#region src/unwrap/unwrapOrDefault.ts
|
|
1102
|
+
/**
|
|
1103
|
+
* Alias for `unwrapOr`.
|
|
1104
|
+
* Equivalent to Rust `unwrap_or_default` (with an explicit default value).
|
|
1105
|
+
*/
|
|
1106
|
+
function unwrapOrDefault(result, defaultValue) {
|
|
1107
|
+
return unwrapOr(result, defaultValue);
|
|
1108
|
+
}
|
|
1109
|
+
|
|
1110
|
+
//#endregion
|
|
1111
|
+
//#region src/unwrap/unwrapOrThrow.ts
|
|
1112
|
+
/**
|
|
1113
|
+
* Returns the value or throws the original Err value (not wrapped).
|
|
1114
|
+
* Useful to keep `Error` instances with stack traces.
|
|
1115
|
+
*/
|
|
1116
|
+
function unwrapOrThrow(result) {
|
|
1117
|
+
if (result.isOk()) return result.value;
|
|
1118
|
+
if (result.isErr()) throw result.error;
|
|
1119
|
+
throw new Error("Unreachable: Result is neither Ok nor Err");
|
|
1120
|
+
}
|
|
1121
|
+
|
|
1122
|
+
//#endregion
|
|
1123
|
+
//#region src/unwrap/unwrapErr.ts
|
|
1124
|
+
/**
|
|
1125
|
+
* Returns the error or throws an Error.
|
|
1126
|
+
* Equivalent to Rust `unwrap_err`.
|
|
1127
|
+
*/
|
|
1128
|
+
function unwrapErr(result) {
|
|
1129
|
+
if (result.isErr()) return result.error;
|
|
1130
|
+
if (result.isOk()) throw new Error(`Called unwrapErr() on Ok: ${String(result.value)}`);
|
|
1131
|
+
throw new Error("Unreachable: Result is neither Ok nor Err");
|
|
1132
|
+
}
|
|
1133
|
+
|
|
1134
|
+
//#endregion
|
|
1135
|
+
//#region src/unwrap/expectResult.ts
|
|
1136
|
+
/**
|
|
1137
|
+
* Returns the value or throws an Error with a custom message.
|
|
1138
|
+
* Equivalent to Rust `expect`.
|
|
1139
|
+
*/
|
|
1140
|
+
function expectResult(result, message) {
|
|
1141
|
+
if (result.isOk()) return result.value;
|
|
1142
|
+
throw new Error(message);
|
|
1143
|
+
}
|
|
1144
|
+
|
|
1145
|
+
//#endregion
|
|
1146
|
+
//#region src/unwrap/expectErr.ts
|
|
1147
|
+
/**
|
|
1148
|
+
* Returns the error or throws an Error with a custom message.
|
|
1149
|
+
* Equivalent to Rust `expect_err`.
|
|
1150
|
+
*/
|
|
1151
|
+
function expectErr(result, message) {
|
|
1152
|
+
if (result.isErr()) return result.error;
|
|
1153
|
+
throw new Error(message);
|
|
1154
|
+
}
|
|
1155
|
+
|
|
1156
|
+
//#endregion
|
|
1157
|
+
//#region src/combinators/and.ts
|
|
1158
|
+
/**
|
|
1159
|
+
* Combines two Results. Returns the second only if the first is Ok.
|
|
1160
|
+
* Equivalent to Rust `and`.
|
|
1161
|
+
*/
|
|
1162
|
+
function and(result, other) {
|
|
1163
|
+
return result.isOk() ? other : result;
|
|
1164
|
+
}
|
|
1165
|
+
|
|
1166
|
+
//#endregion
|
|
1167
|
+
//#region src/combinators/or.ts
|
|
1168
|
+
/**
|
|
1169
|
+
* Fallback to another Result when the first is Err.
|
|
1170
|
+
* Equivalent to Rust `or`.
|
|
1171
|
+
*/
|
|
1172
|
+
function or(result, other) {
|
|
1173
|
+
return result.isOk() ? result : other;
|
|
1174
|
+
}
|
|
1175
|
+
|
|
1176
|
+
//#endregion
|
|
1177
|
+
//#region src/combinators/orElse.ts
|
|
1178
|
+
/**
|
|
1179
|
+
* Fallback using a function that returns a Result.
|
|
1180
|
+
* Equivalent to Rust `or_else`.
|
|
1181
|
+
*/
|
|
1182
|
+
function orElse(result, fn) {
|
|
1183
|
+
if (result.isOk()) return result;
|
|
1184
|
+
if (result.isErr()) return fn(result.error);
|
|
1185
|
+
throw new Error("Unreachable: Result is neither Ok nor Err");
|
|
1186
|
+
}
|
|
1187
|
+
|
|
1188
|
+
//#endregion
|
|
1189
|
+
//#region src/combinators/mapOr.ts
|
|
1190
|
+
/**
|
|
1191
|
+
* Transforms the value or returns a default value.
|
|
1192
|
+
* Equivalent to Rust `map_or`.
|
|
1193
|
+
*/
|
|
1194
|
+
function mapOr(result, defaultValue, fn) {
|
|
1195
|
+
if (result.isOk()) return fn(result.value);
|
|
1196
|
+
return defaultValue;
|
|
1197
|
+
}
|
|
1198
|
+
|
|
1199
|
+
//#endregion
|
|
1200
|
+
//#region src/combinators/mapOrElse.ts
|
|
1201
|
+
/**
|
|
1202
|
+
* Transforms the value or computes a default value with a function.
|
|
1203
|
+
* Equivalent to Rust `map_or_else`.
|
|
1204
|
+
*/
|
|
1205
|
+
function mapOrElse(result, defaultFn, fn) {
|
|
1206
|
+
if (result.isOk()) return fn(result.value);
|
|
1207
|
+
if (result.isErr()) return defaultFn(result.error);
|
|
1208
|
+
throw new Error("Unreachable: Result is neither Ok nor Err");
|
|
1209
|
+
}
|
|
1210
|
+
|
|
1211
|
+
//#endregion
|
|
1212
|
+
//#region src/combinators/zip.ts
|
|
1213
|
+
function zipImpl(left, right) {
|
|
1214
|
+
if (left.isErr()) return left;
|
|
1215
|
+
if (right.isErr()) return right;
|
|
1216
|
+
if (left.isOk() && right.isOk()) return ok([left.value, right.value]);
|
|
1217
|
+
throw new Error("Unreachable: Result is neither Ok nor Err");
|
|
1218
|
+
}
|
|
1219
|
+
function zip(...args) {
|
|
1220
|
+
if (args.length === 1) {
|
|
1221
|
+
const right$1 = args[0];
|
|
1222
|
+
return (left$1) => zipImpl(left$1, right$1);
|
|
1223
|
+
}
|
|
1224
|
+
const [left, right] = args;
|
|
1225
|
+
return zipImpl(left, right);
|
|
1226
|
+
}
|
|
1227
|
+
function combineImpl(left, right) {
|
|
1228
|
+
if (left.isOk() && right.isOk()) return ok([left.value, right.value]);
|
|
1229
|
+
const errors = [];
|
|
1230
|
+
if (left.isErr()) errors.push(left.error);
|
|
1231
|
+
if (right.isErr()) errors.push(right.error);
|
|
1232
|
+
return err(errors);
|
|
1233
|
+
}
|
|
1234
|
+
function combine(...args) {
|
|
1235
|
+
if (args.length === 1) {
|
|
1236
|
+
const right$1 = args[0];
|
|
1237
|
+
return (left$1) => combineImpl(left$1, right$1);
|
|
1238
|
+
}
|
|
1239
|
+
const [left, right] = args;
|
|
1240
|
+
return combineImpl(left, right);
|
|
1241
|
+
}
|
|
1242
|
+
|
|
1243
|
+
//#endregion
|
|
1244
|
+
//#region src/combinators/swap.ts
|
|
1245
|
+
/**
|
|
1246
|
+
* Swaps Ok and Err.
|
|
1247
|
+
* Result<T, E> → Result<E, T>
|
|
1248
|
+
*/
|
|
1249
|
+
function swap(result) {
|
|
1250
|
+
if (result.isOk()) return err(result.value);
|
|
1251
|
+
if (result.isErr()) return ok(result.error);
|
|
1252
|
+
throw new Error("Unreachable: Result is neither Ok nor Err");
|
|
1253
|
+
}
|
|
1254
|
+
|
|
1255
|
+
//#endregion
|
|
1256
|
+
//#region src/collections/sequence.ts
|
|
1257
|
+
/**
|
|
1258
|
+
* Combines a list of Results into a Result of a list.
|
|
1259
|
+
* Short-circuits on the first Err.
|
|
1260
|
+
* Analogous to Rust `collect::<Result<Vec<_>, _>>()`.
|
|
1261
|
+
*/
|
|
1262
|
+
function sequence(results) {
|
|
1263
|
+
const values = [];
|
|
1264
|
+
for (const result of results) {
|
|
1265
|
+
if (result.isOk()) {
|
|
1266
|
+
values.push(result.value);
|
|
1267
|
+
continue;
|
|
1268
|
+
}
|
|
1269
|
+
if (result.isErr()) return result;
|
|
1270
|
+
throw new Error("Unreachable: Result is neither Ok nor Err");
|
|
1271
|
+
}
|
|
1272
|
+
return ok(values);
|
|
1273
|
+
}
|
|
1274
|
+
/**
|
|
1275
|
+
* Alias for `sequence`.
|
|
1276
|
+
*/
|
|
1277
|
+
function all(results) {
|
|
1278
|
+
return sequence(results);
|
|
1279
|
+
}
|
|
1280
|
+
|
|
1281
|
+
//#endregion
|
|
1282
|
+
//#region src/collections/sequenceRecord.ts
|
|
1283
|
+
/**
|
|
1284
|
+
* Like `sequence`, but for records/objects.
|
|
1285
|
+
* Short-circuits on the first Err.
|
|
1286
|
+
*/
|
|
1287
|
+
function sequenceRecord(record) {
|
|
1288
|
+
const out = {};
|
|
1289
|
+
for (const key of Object.keys(record)) {
|
|
1290
|
+
const result = record[key];
|
|
1291
|
+
if (!result) throw new Error(`Missing Result for key "${String(key)}"`);
|
|
1292
|
+
if (result.isOk()) {
|
|
1293
|
+
out[key] = result.value;
|
|
1294
|
+
continue;
|
|
1295
|
+
}
|
|
1296
|
+
if (result.isErr()) return result;
|
|
1297
|
+
throw new Error("Unreachable: Result is neither Ok nor Err");
|
|
1298
|
+
}
|
|
1299
|
+
return ok(out);
|
|
1300
|
+
}
|
|
1301
|
+
|
|
1302
|
+
//#endregion
|
|
1303
|
+
//#region src/collections/collectFirstOk.ts
|
|
1304
|
+
/**
|
|
1305
|
+
* Parse a set of `Result`s, short-circuits when an input value is `Ok`.
|
|
1306
|
+
* If no `Ok` is found, returns an `Err` containing the collected error values.
|
|
1307
|
+
* Useful for "try multiple approaches until one works" patterns.
|
|
1308
|
+
*/
|
|
1309
|
+
function collectFirstOk(results) {
|
|
1310
|
+
const errors = [];
|
|
1311
|
+
for (const result of results) {
|
|
1312
|
+
if (result.isOk()) return ok(result.value);
|
|
1313
|
+
if (result.isErr()) {
|
|
1314
|
+
errors.push(result.error);
|
|
1315
|
+
continue;
|
|
1316
|
+
}
|
|
1317
|
+
throw new Error("Unreachable: Result is neither Ok nor Err");
|
|
1318
|
+
}
|
|
1319
|
+
return err(errors);
|
|
1320
|
+
}
|
|
1321
|
+
|
|
1322
|
+
//#endregion
|
|
1323
|
+
//#region src/collections/collectFirstOkAsync.ts
|
|
1324
|
+
/**
|
|
1325
|
+
* Async version of collectFirstOk.
|
|
1326
|
+
*
|
|
1327
|
+
* - Accepts already-started promises or "thunks" (`() => Awaitable<Result<...>>`).
|
|
1328
|
+
* - Processes inputs strictly sequentially (like `for ... of` + `await`).
|
|
1329
|
+
* - Returns the first `Ok` and collects all errors when no `Ok` is found.
|
|
1330
|
+
*/
|
|
1331
|
+
async function collectFirstOkAsync(inputs) {
|
|
1332
|
+
const errors = [];
|
|
1333
|
+
for (const input of inputs) try {
|
|
1334
|
+
const result = await (typeof input === "function" ? input() : input);
|
|
1335
|
+
if (result.isOk()) return ok(result.value);
|
|
1336
|
+
if (result.isErr()) {
|
|
1337
|
+
errors.push(result.error);
|
|
1338
|
+
continue;
|
|
1339
|
+
}
|
|
1340
|
+
throw new Error("Unreachable: Result is neither Ok nor Err");
|
|
1341
|
+
} catch (error) {
|
|
1342
|
+
errors.push(error);
|
|
1343
|
+
}
|
|
1344
|
+
return err(errors);
|
|
1345
|
+
}
|
|
1346
|
+
|
|
1347
|
+
//#endregion
|
|
1348
|
+
//#region src/collections/collectFirstOkRaceAsync.ts
|
|
1349
|
+
/**
|
|
1350
|
+
* Parallel/race variant of `collectFirstOkAsync`.
|
|
1351
|
+
*
|
|
1352
|
+
* - Starts all inputs immediately (promises or thunks).
|
|
1353
|
+
* - Returns the first `Ok` as soon as it is available.
|
|
1354
|
+
* - If no `Ok` is found, returns an `Err` with all error values (in input order).
|
|
1355
|
+
* - **Note**: There is no cancellation logic. All inputs keep running even after the first `Ok` is found.
|
|
1356
|
+
*/
|
|
1357
|
+
async function collectFirstOkRaceAsync(inputs) {
|
|
1358
|
+
if (inputs.length === 0) return err([]);
|
|
1359
|
+
const UNSET = Symbol("unset");
|
|
1360
|
+
const errorsByIndex = Array(inputs.length).fill(UNSET);
|
|
1361
|
+
return new Promise((resolve) => {
|
|
1362
|
+
let done = false;
|
|
1363
|
+
let remaining = inputs.length;
|
|
1364
|
+
const finishAllErr = () => {
|
|
1365
|
+
const errors = [];
|
|
1366
|
+
for (const entry of errorsByIndex) if (entry !== UNSET) errors.push(entry);
|
|
1367
|
+
resolve(err(errors));
|
|
1368
|
+
};
|
|
1369
|
+
const settleError = (index, errorValue) => {
|
|
1370
|
+
if (done) return;
|
|
1371
|
+
errorsByIndex[index] = errorValue;
|
|
1372
|
+
remaining -= 1;
|
|
1373
|
+
if (remaining === 0) {
|
|
1374
|
+
done = true;
|
|
1375
|
+
finishAllErr();
|
|
1376
|
+
}
|
|
1377
|
+
};
|
|
1378
|
+
inputs.forEach((input, index) => {
|
|
1379
|
+
Promise.resolve().then(() => typeof input === "function" ? input() : input).then((result) => {
|
|
1380
|
+
if (done) return;
|
|
1381
|
+
if (result.isOk()) {
|
|
1382
|
+
done = true;
|
|
1383
|
+
resolve(ok(result.value));
|
|
1384
|
+
return;
|
|
1385
|
+
}
|
|
1386
|
+
if (result.isErr()) {
|
|
1387
|
+
settleError(index, result.error);
|
|
1388
|
+
return;
|
|
1389
|
+
}
|
|
1390
|
+
settleError(index, /* @__PURE__ */ new Error("Unreachable: Result is neither Ok nor Err"));
|
|
1391
|
+
}).catch((caught) => {
|
|
1392
|
+
settleError(index, caught);
|
|
1393
|
+
});
|
|
1394
|
+
});
|
|
1395
|
+
});
|
|
1396
|
+
}
|
|
1397
|
+
|
|
1398
|
+
//#endregion
|
|
1399
|
+
//#region src/collections/collectAllErrors.ts
|
|
1400
|
+
/**
|
|
1401
|
+
* Combines a list of Results.
|
|
1402
|
+
* Returns Ok(values) only if all are Ok, otherwise Err([errors]).
|
|
1403
|
+
*/
|
|
1404
|
+
function collectAllErrors(results) {
|
|
1405
|
+
const values = [];
|
|
1406
|
+
const errors = [];
|
|
1407
|
+
for (const result of results) {
|
|
1408
|
+
if (result.isOk()) {
|
|
1409
|
+
values.push(result.value);
|
|
1410
|
+
continue;
|
|
1411
|
+
}
|
|
1412
|
+
if (result.isErr()) {
|
|
1413
|
+
errors.push(result.error);
|
|
1414
|
+
continue;
|
|
1415
|
+
}
|
|
1416
|
+
throw new Error("Unreachable: Result is neither Ok nor Err");
|
|
1417
|
+
}
|
|
1418
|
+
return errors.length === 0 ? ok(values) : err(errors);
|
|
1419
|
+
}
|
|
1420
|
+
|
|
1421
|
+
//#endregion
|
|
1422
|
+
//#region src/collections/partition.ts
|
|
1423
|
+
/**
|
|
1424
|
+
* Partitions Results into Ok values and Err errors.
|
|
1425
|
+
*/
|
|
1426
|
+
function partition(results) {
|
|
1427
|
+
const oks = [];
|
|
1428
|
+
const errs = [];
|
|
1429
|
+
for (const result of results) {
|
|
1430
|
+
if (result.isOk()) {
|
|
1431
|
+
oks.push(result.value);
|
|
1432
|
+
continue;
|
|
1433
|
+
}
|
|
1434
|
+
if (result.isErr()) {
|
|
1435
|
+
errs.push(result.error);
|
|
1436
|
+
continue;
|
|
1437
|
+
}
|
|
1438
|
+
throw new Error("Unreachable: Result is neither Ok nor Err");
|
|
1439
|
+
}
|
|
1440
|
+
return [oks, errs];
|
|
1441
|
+
}
|
|
1442
|
+
|
|
1443
|
+
//#endregion
|
|
1444
|
+
//#region src/collections/flatten.ts
|
|
1445
|
+
/**
|
|
1446
|
+
* Flacht ein nested Result ab.
|
|
1447
|
+
* Result<Result<T, E>, E> → Result<T, E>
|
|
1448
|
+
* Entspricht Rust `flatten`.
|
|
1449
|
+
*/
|
|
1450
|
+
function flatten(result) {
|
|
1451
|
+
if (result.isOk()) return result.value;
|
|
1452
|
+
return result;
|
|
1453
|
+
}
|
|
1454
|
+
|
|
1455
|
+
//#endregion
|
|
1456
|
+
//#region src/utils/isOk.ts
|
|
1457
|
+
/**
|
|
1458
|
+
* Checks whether a Result is Ok.
|
|
1459
|
+
* Pure function alternative to the instance method.
|
|
1460
|
+
*/
|
|
1461
|
+
function isOk(result) {
|
|
1462
|
+
return result.isOk();
|
|
1463
|
+
}
|
|
1464
|
+
|
|
1465
|
+
//#endregion
|
|
1466
|
+
//#region src/utils/isErr.ts
|
|
1467
|
+
/**
|
|
1468
|
+
* Checks whether a Result is Err.
|
|
1469
|
+
* Pure function alternative to the instance method.
|
|
1470
|
+
*/
|
|
1471
|
+
function isErr(result) {
|
|
1472
|
+
return result.isErr();
|
|
1473
|
+
}
|
|
1474
|
+
|
|
1475
|
+
//#endregion
|
|
1476
|
+
//#region src/utils/contains.ts
|
|
1477
|
+
/**
|
|
1478
|
+
* Checks whether the Result contains a specific value.
|
|
1479
|
+
* Equivalent to Rust `contains`.
|
|
1480
|
+
*/
|
|
1481
|
+
function contains(result, value) {
|
|
1482
|
+
if (!result.isOk()) return false;
|
|
1483
|
+
return result.value === value;
|
|
1484
|
+
}
|
|
1485
|
+
|
|
1486
|
+
//#endregion
|
|
1487
|
+
//#region src/utils/containsErr.ts
|
|
1488
|
+
/**
|
|
1489
|
+
* Checks whether the Result contains a specific error.
|
|
1490
|
+
* Analogous to `contains` for the Err case.
|
|
1491
|
+
*/
|
|
1492
|
+
function containsErr(result, error) {
|
|
1493
|
+
if (!result.isErr()) return false;
|
|
1494
|
+
return result.error === error;
|
|
1495
|
+
}
|
|
1496
|
+
|
|
1497
|
+
//#endregion
|
|
1498
|
+
export { Result, all, and, bimap, collectAllErrors, collectFirstOk, collectFirstOkAsync, collectFirstOkRaceAsync, combine, contains, containsErr, err, expectErr, expectResult, filter, filterAsync, flatMap, flatMapAsync, flatten, fold, foldAsync, fromNullable, fromPromise, gen, isErr, isOk, isResult, map, mapAsync, mapBoth, mapErr, mapErrAsync, mapOr, mapOrElse, match, matchAsync, ok, okIf, okIfLazy, or, orElse, partition, recover, recoverWith, sequence, sequenceRecord, swap, tap, tapAsync, task, toNullable, toPromise, tryCatch, tryCatchAsync, tryFn, tryMap, tryMapAsync, unwrap, unwrapErr, unwrapOr, unwrapOrDefault, unwrapOrElse, unwrapOrThrow, zip };
|
|
1499
|
+
//# sourceMappingURL=index.mjs.map
|