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