happy-rusty 1.5.0 → 1.6.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.
Files changed (42) hide show
  1. package/CHANGELOG.md +206 -0
  2. package/README.cn.md +265 -19
  3. package/README.md +261 -21
  4. package/dist/main.cjs +382 -32
  5. package/dist/main.cjs.map +1 -1
  6. package/dist/main.mjs +374 -33
  7. package/dist/main.mjs.map +1 -1
  8. package/dist/types.d.ts +2002 -52
  9. package/package.json +37 -24
  10. package/dist/types.d.ts.map +0 -1
  11. package/docs/README.md +0 -47
  12. package/docs/functions/Err.md +0 -46
  13. package/docs/functions/Ok.md +0 -70
  14. package/docs/functions/Some.md +0 -45
  15. package/docs/functions/isOption.md +0 -35
  16. package/docs/functions/isResult.md +0 -36
  17. package/docs/functions/promiseToAsyncResult.md +0 -50
  18. package/docs/interfaces/None.md +0 -979
  19. package/docs/interfaces/Option.md +0 -857
  20. package/docs/interfaces/Result.md +0 -903
  21. package/docs/type-aliases/AsyncIOResult.md +0 -24
  22. package/docs/type-aliases/AsyncOption.md +0 -24
  23. package/docs/type-aliases/AsyncResult.md +0 -25
  24. package/docs/type-aliases/AsyncVoidIOResult.md +0 -17
  25. package/docs/type-aliases/AsyncVoidResult.md +0 -23
  26. package/docs/type-aliases/IOResult.md +0 -24
  27. package/docs/type-aliases/VoidIOResult.md +0 -17
  28. package/docs/type-aliases/VoidResult.md +0 -23
  29. package/docs/variables/None.md +0 -18
  30. package/docs/variables/RESULT_FALSE.md +0 -18
  31. package/docs/variables/RESULT_TRUE.md +0 -18
  32. package/docs/variables/RESULT_VOID.md +0 -17
  33. package/docs/variables/RESULT_ZERO.md +0 -18
  34. package/src/enum/constants.ts +0 -30
  35. package/src/enum/core.ts +0 -635
  36. package/src/enum/defines.ts +0 -45
  37. package/src/enum/extensions.ts +0 -31
  38. package/src/enum/mod.ts +0 -6
  39. package/src/enum/prelude.ts +0 -619
  40. package/src/enum/symbols.ts +0 -9
  41. package/src/enum/utils.ts +0 -27
  42. package/src/mod.ts +0 -1
package/dist/main.mjs CHANGED
@@ -1,5 +1,5 @@
1
- const OptionKindSymbol = Symbol("Option kind");
2
- const ResultKindSymbol = Symbol("Result kind");
1
+ const OptionKindSymbol = /* @__PURE__ */ Symbol("Option kind");
2
+ const ResultKindSymbol = /* @__PURE__ */ Symbol("Result kind");
3
3
 
4
4
  function isOption(o) {
5
5
  return o != null && typeof o === "object" && OptionKindSymbol in o;
@@ -9,7 +9,7 @@ function isResult(r) {
9
9
  }
10
10
 
11
11
  function Some(value) {
12
- const some = {
12
+ const some = Object.freeze({
13
13
  [Symbol.toStringTag]: "Option",
14
14
  [OptionKindSymbol]: "Some",
15
15
  isSome() {
@@ -24,6 +24,12 @@ function Some(value) {
24
24
  isSomeAndAsync(predicate) {
25
25
  return predicate(value);
26
26
  },
27
+ isNoneOr(predicate) {
28
+ return predicate(value);
29
+ },
30
+ isNoneOrAsync(predicate) {
31
+ return predicate(value);
32
+ },
27
33
  expect(_msg) {
28
34
  return value;
29
35
  },
@@ -46,17 +52,15 @@ function Some(value) {
46
52
  return Ok(value);
47
53
  },
48
54
  transpose() {
49
- const r = value;
50
- assertResult(r);
51
- return r.isOk() ? Ok(Some(r.unwrap())) : Err(r.unwrapErr());
55
+ assertResult(value);
56
+ return value.isOk() ? Ok(Some(value.unwrap())) : Err(value.unwrapErr());
52
57
  },
53
58
  filter(predicate) {
54
59
  return predicate(value) ? some : None;
55
60
  },
56
61
  flatten() {
57
- const o = value;
58
- assertOption(o);
59
- return o;
62
+ assertOption(value);
63
+ return value;
60
64
  },
61
65
  map(fn) {
62
66
  return Some(fn(value));
@@ -78,7 +82,7 @@ function Some(value) {
78
82
  unzip() {
79
83
  const tuple = value;
80
84
  if (!Array.isArray(tuple) || tuple.length !== 2) {
81
- throw new TypeError("Unzip format is incorrect.");
85
+ throw new TypeError(`Option::unzip() requires a 2-element tuple, received ${Array.isArray(tuple) ? `array with ${tuple.length} elements` : typeof tuple}.`);
82
86
  }
83
87
  const [a, b] = tuple;
84
88
  return [Some(a), Some(b)];
@@ -117,7 +121,7 @@ function Some(value) {
117
121
  toString() {
118
122
  return `Some(${value})`;
119
123
  }
120
- };
124
+ });
121
125
  return some;
122
126
  }
123
127
  const None = Object.freeze({
@@ -135,11 +139,17 @@ const None = Object.freeze({
135
139
  isSomeAndAsync(_predicate) {
136
140
  return Promise.resolve(false);
137
141
  },
142
+ isNoneOr(_predicate) {
143
+ return true;
144
+ },
145
+ isNoneOrAsync(_predicate) {
146
+ return Promise.resolve(true);
147
+ },
138
148
  expect(msg) {
139
149
  throw new TypeError(msg);
140
150
  },
141
151
  unwrap() {
142
- throw new TypeError("Called `Option::unwrap()` on a `None` value");
152
+ throw new TypeError("Option::unwrap() called on a `None` value.");
143
153
  },
144
154
  unwrapOr(defaultValue) {
145
155
  return defaultValue;
@@ -218,7 +228,7 @@ const None = Object.freeze({
218
228
  }
219
229
  });
220
230
  function Ok(value) {
221
- const ok = {
231
+ const ok = Object.freeze({
222
232
  [Symbol.toStringTag]: "Result",
223
233
  [ResultKindSymbol]: "Ok",
224
234
  isOk() {
@@ -258,7 +268,7 @@ function Ok(value) {
258
268
  throw new TypeError(`${msg}: ${value}`);
259
269
  },
260
270
  unwrapErr() {
261
- throw new TypeError("Called `Result::unwrapErr()` on an `Ok` value");
271
+ throw new TypeError("Result::unwrapErr() called on an `Ok` value.");
262
272
  },
263
273
  ok() {
264
274
  return Some(value);
@@ -267,9 +277,8 @@ function Ok(value) {
267
277
  return None;
268
278
  },
269
279
  transpose() {
270
- const o = value;
271
- assertOption(o);
272
- return o.isSome() ? Some(Ok(o.unwrap())) : None;
280
+ assertOption(value);
281
+ return value.isSome() ? Some(Ok(value.unwrap())) : None;
273
282
  },
274
283
  map(fn) {
275
284
  return Ok(fn(value));
@@ -284,9 +293,8 @@ function Ok(value) {
284
293
  return fn(value);
285
294
  },
286
295
  flatten() {
287
- const r = value;
288
- assertResult(r);
289
- return r;
296
+ assertResult(value);
297
+ return value;
290
298
  },
291
299
  and(other) {
292
300
  assertResult(other);
@@ -322,16 +330,16 @@ function Ok(value) {
322
330
  return ok;
323
331
  },
324
332
  asErr() {
325
- throw new TypeError("Called `Result::asErr()` on an `Ok` value");
333
+ throw new TypeError("Result::asErr() called on an `Ok` value.");
326
334
  },
327
335
  toString() {
328
336
  return `Ok(${value})`;
329
337
  }
330
- };
338
+ });
331
339
  return ok;
332
340
  }
333
341
  function Err(error) {
334
- const err = {
342
+ const err = Object.freeze({
335
343
  [Symbol.toStringTag]: "Result",
336
344
  [ResultKindSymbol]: "Err",
337
345
  isOk() {
@@ -356,7 +364,7 @@ function Err(error) {
356
364
  throw new TypeError(`${msg}: ${error}`);
357
365
  },
358
366
  unwrap() {
359
- throw new TypeError("Called `Result::unwrap()` on an `Err` value");
367
+ throw new TypeError("Result::unwrap() called on an `Err` value.");
360
368
  },
361
369
  unwrapOr(defaultValue) {
362
370
  return defaultValue;
@@ -428,7 +436,7 @@ function Err(error) {
428
436
  return other.isErr() && other.unwrapErr() === error;
429
437
  },
430
438
  asOk() {
431
- throw new TypeError("Called `Result::asOk()` on an `Err` value");
439
+ throw new TypeError("Result::asOk() called on an `Err` value.");
432
440
  },
433
441
  asErr() {
434
442
  return err;
@@ -436,17 +444,33 @@ function Err(error) {
436
444
  toString() {
437
445
  return `Err(${error})`;
438
446
  }
439
- };
447
+ });
440
448
  return err;
441
449
  }
450
+ function safeStringify(value) {
451
+ try {
452
+ if (value === null) {
453
+ return "null";
454
+ }
455
+ if (value === void 0) {
456
+ return "undefined";
457
+ }
458
+ if (typeof value === "object") {
459
+ return Object.prototype.toString.call(value);
460
+ }
461
+ return String(value);
462
+ } catch {
463
+ return "[unable to stringify]";
464
+ }
465
+ }
442
466
  function assertOption(o) {
443
467
  if (!isOption(o)) {
444
- throw new TypeError(`This(${o}) is not an Option`);
468
+ throw new TypeError(`Expected an Option, but received: ${safeStringify(o)}.`);
445
469
  }
446
470
  }
447
471
  function assertResult(r) {
448
472
  if (!isResult(r)) {
449
- throw new TypeError(`This(${r}) is not a Result`);
473
+ throw new TypeError(`Expected a Result, but received: ${safeStringify(r)}.`);
450
474
  }
451
475
  }
452
476
 
@@ -455,13 +479,330 @@ const RESULT_FALSE = Ok(false);
455
479
  const RESULT_ZERO = Ok(0);
456
480
  const RESULT_VOID = Ok();
457
481
 
458
- function promiseToAsyncResult(p) {
459
- return p.then((x) => {
460
- return Ok(x);
461
- }).catch((err) => {
482
+ async function promiseToAsyncResult(p) {
483
+ try {
484
+ return Ok(await p);
485
+ } catch (err) {
462
486
  return Err(err);
487
+ }
488
+ }
489
+
490
+ const ControlFlowKindSymbol = /* @__PURE__ */ Symbol("ControlFlow kind");
491
+
492
+ function Break(value) {
493
+ const brk = Object.freeze({
494
+ [Symbol.toStringTag]: "ControlFlow",
495
+ [ControlFlowKindSymbol]: "Break",
496
+ isBreak() {
497
+ return true;
498
+ },
499
+ isContinue() {
500
+ return false;
501
+ },
502
+ breakValue() {
503
+ return Some(value);
504
+ },
505
+ continueValue() {
506
+ return None;
507
+ },
508
+ mapBreak(fn) {
509
+ return Break(fn(value));
510
+ },
511
+ mapContinue(_fn) {
512
+ return brk;
513
+ },
514
+ breakOk() {
515
+ return Ok(value);
516
+ },
517
+ continueOk() {
518
+ return Err(value);
519
+ },
520
+ toString() {
521
+ return `Break(${value})`;
522
+ }
523
+ });
524
+ return brk;
525
+ }
526
+ function Continue(value) {
527
+ const cont = Object.freeze({
528
+ [Symbol.toStringTag]: "ControlFlow",
529
+ [ControlFlowKindSymbol]: "Continue",
530
+ isBreak() {
531
+ return false;
532
+ },
533
+ isContinue() {
534
+ return true;
535
+ },
536
+ breakValue() {
537
+ return None;
538
+ },
539
+ continueValue() {
540
+ return Some(value);
541
+ },
542
+ mapBreak(_fn) {
543
+ return cont;
544
+ },
545
+ mapContinue(fn) {
546
+ return Continue(fn(value));
547
+ },
548
+ breakOk() {
549
+ return Err(value);
550
+ },
551
+ continueOk() {
552
+ return Ok(value);
553
+ },
554
+ toString() {
555
+ return `Continue(${value})`;
556
+ }
557
+ });
558
+ return cont;
559
+ }
560
+
561
+ function isControlFlow(cf) {
562
+ return cf != null && typeof cf === "object" && ControlFlowKindSymbol in cf;
563
+ }
564
+
565
+ function Lazy(fn) {
566
+ let value;
567
+ let initialized = false;
568
+ return Object.freeze({
569
+ [Symbol.toStringTag]: "Lazy",
570
+ force() {
571
+ if (!initialized) {
572
+ value = fn();
573
+ initialized = true;
574
+ }
575
+ return value;
576
+ },
577
+ get() {
578
+ return initialized ? Some(value) : None;
579
+ },
580
+ isInitialized() {
581
+ return initialized;
582
+ },
583
+ toString() {
584
+ return initialized ? `Lazy(${value})` : "Lazy(<uninitialized>)";
585
+ }
586
+ });
587
+ }
588
+ function LazyAsync(fn) {
589
+ let value;
590
+ let initialized = false;
591
+ let pendingPromise;
592
+ return Object.freeze({
593
+ [Symbol.toStringTag]: "LazyAsync",
594
+ async force() {
595
+ if (initialized) {
596
+ return value;
597
+ }
598
+ if (pendingPromise) {
599
+ return pendingPromise;
600
+ }
601
+ pendingPromise = (async () => {
602
+ try {
603
+ const result = await fn();
604
+ value = result;
605
+ initialized = true;
606
+ return result;
607
+ } finally {
608
+ pendingPromise = void 0;
609
+ }
610
+ })();
611
+ return pendingPromise;
612
+ },
613
+ get() {
614
+ return initialized ? Some(value) : None;
615
+ },
616
+ isInitialized() {
617
+ return initialized;
618
+ },
619
+ toString() {
620
+ return initialized ? `LazyAsync(${value})` : "LazyAsync(<uninitialized>)";
621
+ }
622
+ });
623
+ }
624
+
625
+ function Mutex(value) {
626
+ let currentValue = value;
627
+ let locked = false;
628
+ const waitQueue = [];
629
+ function unlock() {
630
+ if (waitQueue.length > 0) {
631
+ const next = waitQueue.shift();
632
+ next();
633
+ } else {
634
+ locked = false;
635
+ }
636
+ }
637
+ function createGuard() {
638
+ let released = false;
639
+ return Object.freeze({
640
+ [Symbol.toStringTag]: "MutexGuard",
641
+ get value() {
642
+ if (released) {
643
+ throw new Error("MutexGuard has been released.");
644
+ }
645
+ return currentValue;
646
+ },
647
+ set value(newValue) {
648
+ if (released) {
649
+ throw new Error("MutexGuard has been released.");
650
+ }
651
+ currentValue = newValue;
652
+ },
653
+ unlock() {
654
+ if (released) {
655
+ return;
656
+ }
657
+ released = true;
658
+ unlock();
659
+ },
660
+ toString() {
661
+ if (released) {
662
+ return "MutexGuard(<released>)";
663
+ }
664
+ return `MutexGuard(${currentValue})`;
665
+ }
666
+ });
667
+ }
668
+ function lock() {
669
+ if (!locked) {
670
+ locked = true;
671
+ return Promise.resolve(createGuard());
672
+ }
673
+ return new Promise((resolve) => {
674
+ waitQueue.push(() => {
675
+ resolve(createGuard());
676
+ });
677
+ });
678
+ }
679
+ return Object.freeze({
680
+ [Symbol.toStringTag]: "Mutex",
681
+ async withLock(fn) {
682
+ const guard = await lock();
683
+ try {
684
+ return await fn(guard.value);
685
+ } finally {
686
+ guard.unlock();
687
+ }
688
+ },
689
+ lock,
690
+ tryLock() {
691
+ if (locked) {
692
+ return None;
693
+ }
694
+ locked = true;
695
+ return Some(createGuard());
696
+ },
697
+ isLocked() {
698
+ return locked;
699
+ },
700
+ toString() {
701
+ return locked ? "Mutex(<locked>)" : "Mutex(<unlocked>)";
702
+ }
703
+ });
704
+ }
705
+
706
+ function Once() {
707
+ let value;
708
+ let initialized = false;
709
+ let pendingPromise;
710
+ return Object.freeze({
711
+ [Symbol.toStringTag]: "Once",
712
+ get() {
713
+ return initialized ? Some(value) : None;
714
+ },
715
+ set(newValue) {
716
+ if (initialized) {
717
+ return Err(newValue);
718
+ }
719
+ value = newValue;
720
+ initialized = true;
721
+ return Ok(void 0);
722
+ },
723
+ getOrInit(fn) {
724
+ if (!initialized) {
725
+ value = fn();
726
+ initialized = true;
727
+ }
728
+ return value;
729
+ },
730
+ async getOrInitAsync(fn) {
731
+ if (initialized) {
732
+ return value;
733
+ }
734
+ if (pendingPromise) {
735
+ return pendingPromise;
736
+ }
737
+ pendingPromise = (async () => {
738
+ try {
739
+ const result = await fn();
740
+ value = result;
741
+ initialized = true;
742
+ return result;
743
+ } finally {
744
+ pendingPromise = void 0;
745
+ }
746
+ })();
747
+ return pendingPromise;
748
+ },
749
+ getOrTryInit(fn) {
750
+ if (initialized) {
751
+ return Ok(value);
752
+ }
753
+ const result = fn();
754
+ if (result.isOk()) {
755
+ value = result.unwrap();
756
+ initialized = true;
757
+ }
758
+ return result;
759
+ },
760
+ async getOrTryInitAsync(fn) {
761
+ if (initialized) {
762
+ return Ok(value);
763
+ }
764
+ if (pendingPromise) {
765
+ try {
766
+ await pendingPromise;
767
+ return Ok(value);
768
+ } catch {
769
+ }
770
+ }
771
+ pendingPromise = (async () => {
772
+ const result = await fn();
773
+ if (result.isOk()) {
774
+ value = result.unwrap();
775
+ initialized = true;
776
+ return value;
777
+ }
778
+ throw result;
779
+ })();
780
+ try {
781
+ const resultValue = await pendingPromise;
782
+ return Ok(resultValue);
783
+ } catch (errResult) {
784
+ return errResult;
785
+ } finally {
786
+ pendingPromise = void 0;
787
+ }
788
+ },
789
+ take() {
790
+ if (!initialized) {
791
+ return None;
792
+ }
793
+ const taken = value;
794
+ value = void 0;
795
+ initialized = false;
796
+ return Some(taken);
797
+ },
798
+ isInitialized() {
799
+ return initialized;
800
+ },
801
+ toString() {
802
+ return initialized ? `Once(${value})` : "Once(<uninitialized>)";
803
+ }
463
804
  });
464
805
  }
465
806
 
466
- export { Err, None, Ok, RESULT_FALSE, RESULT_TRUE, RESULT_VOID, RESULT_ZERO, Some, isOption, isResult, promiseToAsyncResult };
807
+ export { Break, Continue, Err, Lazy, LazyAsync, Mutex, None, Ok, Once, RESULT_FALSE, RESULT_TRUE, RESULT_VOID, RESULT_ZERO, Some, isControlFlow, isOption, isResult, promiseToAsyncResult };
467
808
  //# sourceMappingURL=main.mjs.map