happy-rusty 1.1.2 → 1.2.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.
@@ -33,6 +33,11 @@ pub enum Option<T> {
33
33
  export interface Option<T> {
34
34
  // #region Internal properties
35
35
 
36
+ /**
37
+ * [object Option].
38
+ */
39
+ [Symbol.toStringTag]: 'Option',
40
+
36
41
  /**
37
42
  * Identify `Some` or `None`.
38
43
  *
@@ -277,6 +282,11 @@ export interface Option<T> {
277
282
  eq(other: Option<T>): boolean;
278
283
 
279
284
  // #endregion
285
+
286
+ /**
287
+ * Custom `toString` implementation that uses the `Option`'s contained value.
288
+ */
289
+ toString(): string;
280
290
  }
281
291
 
282
292
  /**
@@ -330,6 +340,11 @@ pub enum Result<T, E> {
330
340
  export interface Result<T, E> {
331
341
  // #region Internal properties
332
342
 
343
+ /**
344
+ * [object Result].
345
+ */
346
+ [Symbol.toStringTag]: 'Result',
347
+
333
348
  /**
334
349
  * Identify `Ok` or `Err`.
335
350
  *
@@ -588,6 +603,11 @@ export interface Result<T, E> {
588
603
  * @returns `this` but the success result type is `U`.
589
604
  */
590
605
  asErr<U>(): Result<U, E>;
606
+
607
+ /**
608
+ * Custom `toString` implementation that uses the `Result`'s contained value.
609
+ */
610
+ toString(): string;
591
611
  }
592
612
 
593
613
  /**
@@ -645,45 +665,72 @@ export type AsyncIOResult<T> = Promise<IOResult<T>>;
645
665
  */
646
666
  export function Some<T>(value: T): Option<T> {
647
667
  const some: Option<T> = {
668
+ [Symbol.toStringTag]: 'Option',
648
669
  [optionKindSymbol]: 'Some',
649
670
 
650
- isSome: (): true => true,
651
- isNone: (): false => false,
652
- isSomeAnd: (predicate: (value: T) => boolean): boolean => predicate(value),
671
+ isSome(): true {
672
+ return true;
673
+ },
674
+ isNone(): false {
675
+ return false;
676
+ },
677
+ isSomeAnd(predicate: (value: T) => boolean): boolean {
678
+ return predicate(value);
679
+ },
653
680
 
654
- expect: (_msg: string): T => value,
655
- unwrap: (): T => value,
656
- unwrapOr: (_defaultValue: T): T => value,
657
- unwrapOrElse: (_fn: () => T): T => value,
681
+ expect(_msg: string): T {
682
+ return value;
683
+ },
684
+ unwrap(): T {
685
+ return value;
686
+ },
687
+ unwrapOr(_defaultValue: T): T {
688
+ return value;
689
+ },
690
+ unwrapOrElse(_fn: () => T): T {
691
+ return value;
692
+ },
658
693
 
659
- okOr: <E>(_error: E): Result<T, E> => Ok(value),
660
- okOrElse: <E>(_err: () => E): Result<T, E> => Ok(value),
661
- transpose: <T, E>(): Result<Option<T>, E> => {
694
+ okOr<E>(_error: E): Result<T, E> {
695
+ return Ok(value);
696
+ },
697
+ okOrElse<E>(_err: () => E): Result<T, E> {
698
+ return Ok(value);
699
+ },
700
+ transpose<T, E>(): Result<Option<T>, E> {
662
701
  const r = value as unknown as Result<T, E>;
663
702
  assertResult(r);
664
703
  return r.isOk() ? Ok(Some(r.unwrap())) : Err(r.unwrapErr());
665
704
  },
666
705
 
667
- filter: (predicate: (value: T) => boolean): Option<T> => predicate(value) ? some : None,
668
- flatten: <T>(): Option<T> => {
706
+ filter(predicate: (value: T) => boolean): Option<T> {
707
+ return predicate(value) ? some : None;
708
+ },
709
+ flatten<T>(): Option<T> {
669
710
  const o = value as unknown as Option<T>;
670
711
  assertOption(o);
671
712
  return o;
672
713
  },
673
- map: <U>(fn: (value: T) => U): Option<U> => Some(fn(value)),
714
+ map<U>(fn: (value: T) => U): Option<U> {
715
+ return Some(fn(value));
716
+ },
674
717
 
675
- mapOr: <U>(_defaultValue: U, fn: (value: T) => U): U => fn(value),
676
- mapOrElse: <U>(_defaultFn: () => U, fn: (value: T) => U): U => fn(value),
718
+ mapOr<U>(_defaultValue: U, fn: (value: T) => U): U {
719
+ return fn(value);
720
+ },
721
+ mapOrElse<U>(_defaultFn: () => U, fn: (value: T) => U): U {
722
+ return fn(value);
723
+ },
677
724
 
678
- zip: <U>(other: Option<U>): Option<[T, U]> => {
725
+ zip<U>(other: Option<U>): Option<[T, U]> {
679
726
  assertOption(other);
680
727
  return other.isSome() ? Some([value, other.unwrap()]) : None;
681
728
  },
682
- zipWith: <U, R>(other: Option<U>, fn: (value: T, otherValue: U) => R): Option<R> => {
729
+ zipWith<U, R>(other: Option<U>, fn: (value: T, otherValue: U) => R): Option<R> {
683
730
  assertOption(other);
684
731
  return other.isSome() ? Some(fn(value, other.unwrap())) : None;
685
732
  },
686
- unzip: <T, U>(): [Option<T>, Option<U>] => {
733
+ unzip<T, U>(): [Option<T>, Option<U>] {
687
734
  const tuple = value as unknown as [T, U];
688
735
 
689
736
  if (!Array.isArray(tuple) || tuple.length !== 2) {
@@ -694,27 +741,37 @@ export function Some<T>(value: T): Option<T> {
694
741
  return [Some(a), Some(b)];
695
742
  },
696
743
 
697
- and: <U>(other: Option<U>): Option<U> => {
744
+ and<U>(other: Option<U>): Option<U> {
698
745
  assertOption(other);
699
746
  return other;
700
747
  },
701
- andThen: <U>(fn: (value: T) => Option<U>): Option<U> => fn(value),
702
- or: (_other: Option<T>): Option<T> => some,
703
- orElse: (_fn: () => Option<T>): Option<T> => some,
704
- xor: (other: Option<T>): Option<T> => {
748
+ andThen<U>(fn: (value: T) => Option<U>): Option<U> {
749
+ return fn(value);
750
+ },
751
+ or(_other: Option<T>): Option<T> {
752
+ return some;
753
+ },
754
+ orElse(_fn: () => Option<T>): Option<T> {
755
+ return some;
756
+ },
757
+ xor(other: Option<T>): Option<T> {
705
758
  assertOption(other);
706
759
  return other.isSome() ? None : some;
707
760
  },
708
761
 
709
- inspect: (fn: (value: T) => void): Option<T> => {
762
+ inspect(fn: (value: T) => void): Option<T> {
710
763
  fn(value);
711
764
  return some;
712
765
  },
713
766
 
714
- eq: (other: Option<T>): boolean => {
767
+ eq(other: Option<T>): boolean {
715
768
  assertOption(other);
716
769
  return other.isSome() && other.unwrap() === value;
717
770
  },
771
+
772
+ toString(): string {
773
+ return `Some(${ value })`;
774
+ },
718
775
  } as const;
719
776
 
720
777
  return some;
@@ -725,54 +782,99 @@ export function Some<T>(value: T): Option<T> {
725
782
  * This constant is frozen to ensure it is immutable and cannot be altered, preserving the integrity of `None` throughout the application.
726
783
  */
727
784
  export const None = Object.freeze<None>({
785
+ [Symbol.toStringTag]: 'Option',
728
786
  [optionKindSymbol]: 'None',
729
787
 
730
- isSome: (): false => false,
731
- isNone: (): true => true,
732
- isSomeAnd: (_predicate: (value: never) => boolean): false => false,
788
+ isSome(): false {
789
+ return false;
790
+ },
791
+ isNone(): true {
792
+ return true;
793
+ },
794
+ isSomeAnd(_predicate: (value: never) => boolean): false {
795
+ return false;
796
+ },
733
797
 
734
- expect: (msg: string): never => {
798
+ expect(msg: string): never {
735
799
  throw new TypeError(msg);
736
800
  },
737
- unwrap: (): never => {
801
+ unwrap(): never {
738
802
  throw new TypeError('Called `Option::unwrap()` on a `None` value');
739
803
  },
740
- unwrapOr: <T>(defaultValue: T): T => defaultValue,
741
- unwrapOrElse: <T>(fn: () => T): T => fn(),
804
+ unwrapOr<T>(defaultValue: T): T {
805
+ return defaultValue;
806
+ },
807
+ unwrapOrElse<T>(fn: () => T): T {
808
+ return fn();
809
+ },
742
810
 
743
- okOr: <E>(error: E): Result<never, E> => Err(error),
744
- okOrElse: <E>(err: () => E): Result<never, E> => Err(err()),
745
- transpose: (): Result<None, never> => Ok(None),
811
+ okOr<E>(error: E): Result<never, E> {
812
+ return Err(error);
813
+ },
814
+ okOrElse<E>(err: () => E): Result<never, E> {
815
+ return Err(err());
816
+ },
817
+ transpose(): Result<None, never> {
818
+ return Ok(None);
819
+ },
746
820
 
747
- filter: (_predicate: (value: never) => boolean): None => None,
748
- flatten: (): None => None,
749
- map: <U>(_fn: (value: never) => U): None => None,
821
+ filter(_predicate: (value: never) => boolean): None {
822
+ return None;
823
+ },
824
+ flatten(): None {
825
+ return None;
826
+ },
827
+ map<U>(_fn: (value: never) => U): None {
828
+ return None;
829
+ },
750
830
 
751
- mapOr: <U>(defaultValue: U, _fn: (value: never) => U): U => defaultValue,
752
- mapOrElse: <U>(defaultFn: () => U, _fn: (value: never) => U): U => defaultFn(),
831
+ mapOr<U>(defaultValue: U, _fn: (value: never) => U): U {
832
+ return defaultValue;
833
+ },
834
+ mapOrElse<U>(defaultFn: () => U, _fn: (value: never) => U): U {
835
+ return defaultFn();
836
+ },
753
837
 
754
- zip: <U>(_other: Option<U>): None => None,
755
- zipWith: <U, R>(_other: Option<U>, _fn: (value: never, otherValue: U) => R): None => None,
756
- unzip: (): [None, None] => [None, None],
838
+ zip<U>(_other: Option<U>): None {
839
+ return None;
840
+ },
841
+ zipWith<U, R>(_other: Option<U>, _fn: (value: never, otherValue: U) => R): None {
842
+ return None;
843
+ },
844
+ unzip(): [None, None] {
845
+ return [None, None];
846
+ },
757
847
 
758
- and: <U>(_other: Option<U>): None => None,
759
- andThen: <U>(_fn: (value: never) => Option<U>): None => None,
760
- or: <T>(other: Option<T>): Option<T> => {
848
+ and<U>(_other: Option<U>): None {
849
+ return None;
850
+ },
851
+ andThen<U>(_fn: (value: never) => Option<U>): None {
852
+ return None;
853
+ },
854
+ or<T>(other: Option<T>): Option<T> {
761
855
  assertOption(other);
762
856
  return other;
763
857
  },
764
- orElse: <T>(fn: () => Option<T>): Option<T> => fn(),
765
- xor: <T>(other: Option<T>): Option<T> => {
858
+ orElse<T>(fn: () => Option<T>): Option<T> {
859
+ return fn();
860
+ },
861
+ xor<T>(other: Option<T>): Option<T> {
766
862
  assertOption(other);
767
863
  return other.isSome() ? other : None;
768
864
  },
769
865
 
770
- inspect: (_fn: (value: never) => void): None => None,
866
+ inspect(_fn: (value: never) => void): None {
867
+ return None;
868
+ },
771
869
 
772
- eq: <T>(other: Option<T>): boolean => {
870
+ eq<T>(other: Option<T>): boolean {
773
871
  assertOption(other);
774
872
  return other === None;
775
873
  },
874
+
875
+ toString(): string {
876
+ return 'None';
877
+ },
776
878
  }) as None;
777
879
 
778
880
  /**
@@ -794,58 +896,95 @@ export const None = Object.freeze<None>({
794
896
  */
795
897
  export function Ok<T, E>(value: T): Result<T, E> {
796
898
  const ok: Result<T, E> = {
899
+ [Symbol.toStringTag]: 'Result',
797
900
  [resultKindSymbol]: 'Ok',
798
901
 
799
- isOk: (): true => true,
800
- isErr: (): false => false,
801
- isOkAnd: (predicate: (value: T) => boolean): boolean => predicate(value),
802
- isErrAnd: (_predicate: (error: E) => boolean): false => false,
902
+ isOk(): true {
903
+ return true;
904
+ },
905
+ isErr(): false {
906
+ return false;
907
+ },
908
+ isOkAnd(predicate: (value: T) => boolean): boolean {
909
+ return predicate(value);
910
+ },
911
+ isErrAnd(_predicate: (error: E) => boolean): false {
912
+ return false;
913
+ },
803
914
 
804
- expect: (_msg: string): T => value,
805
- unwrap: (): T => value,
806
- unwrapOr: (_defaultValue: T): T => value,
807
- unwrapOrElse: (_fn: (error: E) => T): T => value,
915
+ expect(_msg: string): T {
916
+ return value;
917
+ },
918
+ unwrap(): T {
919
+ return value;
920
+ },
921
+ unwrapOr(_defaultValue: T): T {
922
+ return value;
923
+ },
924
+ unwrapOrElse(_fn: (error: E) => T): T {
925
+ return value;
926
+ },
808
927
 
809
- expectErr: (msg: string): E => {
928
+ expectErr(msg: string): E {
810
929
  throw new TypeError(`${ msg }: ${ value }`);
811
930
  },
812
- unwrapErr: (): E => {
931
+ unwrapErr(): E {
813
932
  throw new TypeError('Called `Result::unwrapErr()` on an `Ok` value');
814
933
  },
815
934
 
816
- ok: (): Option<T> => Some(value),
817
- err: (): None => None,
818
- transpose: <T>(): Option<Result<T, E>> => {
935
+ ok(): Option<T> {
936
+ return Some(value);
937
+ },
938
+ err(): None {
939
+ return None;
940
+ },
941
+ transpose<T>(): Option<Result<T, E>> {
819
942
  const o = value as Option<T>;
820
943
  assertOption(o);
821
944
  return o.isSome() ? Some(Ok(o.unwrap())) : None;
822
945
  },
823
946
 
824
- map: <U>(fn: (value: T) => U): Result<U, E> => Ok(fn(value)),
825
- mapErr: <F>(_fn: (error: E) => F): Result<T, F> => Ok(value),
826
- mapOr: <U>(_defaultValue: U, fn: (value: T) => U): U => fn(value),
827
- mapOrElse: <U>(_defaultFn: (error: E) => U, fn: (value: T) => U): U => fn(value),
828
- flatten: <T>(): Result<T, E> => {
947
+ map<U>(fn: (value: T) => U): Result<U, E> {
948
+ return Ok(fn(value));
949
+ },
950
+ mapErr<F>(_fn: (error: E) => F): Result<T, F> {
951
+ return Ok(value);
952
+ },
953
+ mapOr<U>(_defaultValue: U, fn: (value: T) => U): U {
954
+ return fn(value);
955
+ },
956
+ mapOrElse<U>(_defaultFn: (error: E) => U, fn: (value: T) => U): U {
957
+ return fn(value);
958
+ },
959
+ flatten<T>(): Result<T, E> {
829
960
  const r = value as Result<T, E>;
830
961
  assertResult(r);
831
962
  return r;
832
963
  },
833
964
 
834
- and: <U>(other: Result<U, E>): Result<U, E> => {
965
+ and<U>(other: Result<U, E>): Result<U, E> {
835
966
  assertResult(other);
836
967
  return other;
837
968
  },
838
- or: <F>(_other: Result<T, F>): Result<T, F> => ok as unknown as Result<T, F>,
839
- andThen: <U>(fn: (value: T) => Result<U, E>): Result<U, E> => fn(value),
840
- orElse: <F>(_fn: (error: E) => Result<T, F>): Result<T, F> => ok as unknown as Result<T, F>,
969
+ or<F>(_other: Result<T, F>): Result<T, F> {
970
+ return ok as unknown as Result<T, F>;
971
+ },
972
+ andThen<U>(fn: (value: T) => Result<U, E>): Result<U, E> {
973
+ return fn(value);
974
+ },
975
+ orElse<F>(_fn: (error: E) => Result<T, F>): Result<T, F> {
976
+ return ok as unknown as Result<T, F>;
977
+ },
841
978
 
842
- inspect: (fn: (value: T) => void): Result<T, E> => {
979
+ inspect(fn: (value: T) => void): Result<T, E> {
843
980
  fn(value);
844
981
  return ok;
845
982
  },
846
- inspectErr: (_fn: (error: E) => void): Result<T, E> => ok,
983
+ inspectErr(_fn: (error: E) => void): Result<T, E> {
984
+ return ok;
985
+ },
847
986
 
848
- eq: (other: Result<T, E>): boolean => {
987
+ eq(other: Result<T, E>): boolean {
849
988
  assertResult(other);
850
989
  return other.isOk() && other.unwrap() === value;
851
990
  },
@@ -856,6 +995,10 @@ export function Ok<T, E>(value: T): Result<T, E> {
856
995
  asErr(): never {
857
996
  throw new TypeError('Called `Result::asErr()` on an `Ok` value');
858
997
  },
998
+
999
+ toString(): string {
1000
+ return `Ok(${ value })`;
1001
+ },
859
1002
  } as const;
860
1003
 
861
1004
  return ok;
@@ -880,50 +1023,91 @@ export function Ok<T, E>(value: T): Result<T, E> {
880
1023
  */
881
1024
  export function Err<T, E>(error: E): Result<T, E> {
882
1025
  const err: Result<T, E> = {
1026
+ [Symbol.toStringTag]: 'Result',
883
1027
  [resultKindSymbol]: 'Err',
884
1028
 
885
- isOk: (): false => false,
886
- isErr: (): true => true,
887
- isOkAnd: (_predicate: (value: T) => boolean): false => false,
888
- isErrAnd: (predicate: (error: E) => boolean): boolean => predicate(error),
1029
+ isOk(): false {
1030
+ return false;
1031
+ },
1032
+ isErr(): true {
1033
+ return true;
1034
+ },
1035
+ isOkAnd(_predicate: (value: T) => boolean): false {
1036
+ return false;
1037
+ },
1038
+ isErrAnd(predicate: (error: E) => boolean): boolean {
1039
+ return predicate(error);
1040
+ },
889
1041
 
890
- expect: (msg: string): T => {
1042
+ expect(msg: string): T {
891
1043
  throw new TypeError(`${ msg }: ${ error }`);
892
1044
  },
893
- unwrap: (): T => {
1045
+ unwrap(): T {
894
1046
  throw new TypeError('Called `Result::unwrap()` on an `Err` value');
895
1047
  },
896
- unwrapOr: (defaultValue: T): T => defaultValue,
897
- unwrapOrElse: (fn: (error: E) => T): T => fn(error),
1048
+ unwrapOr(defaultValue: T): T {
1049
+ return defaultValue;
1050
+ },
1051
+ unwrapOrElse(fn: (error: E) => T): T {
1052
+ return fn(error);
1053
+ },
898
1054
 
899
- expectErr: (_msg: string): E => error,
900
- unwrapErr: (): E => error,
1055
+ expectErr(_msg: string): E {
1056
+ return error;
1057
+ },
1058
+ unwrapErr(): E {
1059
+ return error;
1060
+ },
901
1061
 
902
- ok: (): None => None,
903
- err: (): Option<E> => Some(error),
904
- transpose: <T>(): Option<Result<T, E>> => Some(err as unknown as Result<T, E>),
1062
+ ok(): None {
1063
+ return None;
1064
+ },
1065
+ err(): Option<E> {
1066
+ return Some(error);
1067
+ },
1068
+ transpose<T>(): Option<Result<T, E>> {
1069
+ return Some(err as unknown as Result<T, E>);
1070
+ },
905
1071
 
906
- map: <U>(_fn: (value: T) => U): Result<U, E> => err as unknown as Result<U, E>,
907
- mapErr: <F>(fn: (error: E) => F): Result<T, F> => Err(fn(error)),
908
- mapOr: <U>(defaultValue: U, _fn: (value: T) => U): U => defaultValue,
909
- mapOrElse: <U>(defaultFn: (error: E) => U, _fn: (value: T) => U): U => defaultFn(error),
910
- flatten: <T>(): Result<T, E> => err as unknown as Result<T, E>,
1072
+ map<U>(_fn: (value: T) => U): Result<U, E> {
1073
+ return err as unknown as Result<U, E>;
1074
+ },
1075
+ mapErr<F>(fn: (error: E) => F): Result<T, F> {
1076
+ return Err(fn(error));
1077
+ },
1078
+ mapOr<U>(defaultValue: U, _fn: (value: T) => U): U {
1079
+ return defaultValue;
1080
+ },
1081
+ mapOrElse<U>(defaultFn: (error: E) => U, _fn: (value: T) => U): U {
1082
+ return defaultFn(error);
1083
+ },
1084
+ flatten<T>(): Result<T, E> {
1085
+ return err as unknown as Result<T, E>;
1086
+ },
911
1087
 
912
- and: <U>(_other: Result<U, E>): Result<U, E> => err as unknown as Result<U, E>,
913
- or: <F>(other: Result<T, F>): Result<T, F> => {
1088
+ and<U>(_other: Result<U, E>): Result<U, E> {
1089
+ return err as unknown as Result<U, E>;
1090
+ },
1091
+ or<F>(other: Result<T, F>): Result<T, F> {
914
1092
  assertResult(other);
915
1093
  return other;
916
1094
  },
917
- andThen: <U>(_fn: (value: T) => Result<U, E>): Result<U, E> => err as unknown as Result<U, E>,
918
- orElse: <F>(fn: (error: E) => Result<T, F>): Result<T, F> => fn(error),
1095
+ andThen<U>(_fn: (value: T) => Result<U, E>): Result<U, E> {
1096
+ return err as unknown as Result<U, E>;
1097
+ },
1098
+ orElse<F>(fn: (error: E) => Result<T, F>): Result<T, F> {
1099
+ return fn(error);
1100
+ },
919
1101
 
920
- inspect: (_fn: (value: T) => void): Result<T, E> => err,
921
- inspectErr: (fn: (error: E) => void): Result<T, E> => {
1102
+ inspect(_fn: (value: T) => void): Result<T, E> {
1103
+ return err;
1104
+ },
1105
+ inspectErr(fn: (error: E) => void): Result<T, E> {
922
1106
  fn(error);
923
1107
  return err;
924
1108
  },
925
1109
 
926
- eq: (other: Result<T, E>): boolean => {
1110
+ eq(other: Result<T, E>): boolean {
927
1111
  assertResult(other);
928
1112
  return other.isErr() && other.unwrapErr() === error;
929
1113
  },
@@ -934,6 +1118,10 @@ export function Err<T, E>(error: E): Result<T, E> {
934
1118
  asErr<U>(): Result<U, E> {
935
1119
  return err as unknown as Result<U, E>;
936
1120
  },
1121
+
1122
+ toString(): string {
1123
+ return `Err(${ error })`;
1124
+ },
937
1125
  } as const;
938
1126
 
939
1127
  return err;
@@ -947,8 +1135,7 @@ export function Err<T, E>(error: E): Result<T, E> {
947
1135
  * @throws {TypeError} If the value is not an `Option`.
948
1136
  */
949
1137
  function assertOption<T>(o: Option<T>): void {
950
- // `Some` and `None` must be an object.
951
- if (o == null || typeof o !== 'object' || !(optionKindSymbol in o)) {
1138
+ if (!isOption(o)) {
952
1139
  throw new TypeError(`This(${ o }) is not an Option`);
953
1140
  }
954
1141
  }
@@ -962,8 +1149,7 @@ function assertOption<T>(o: Option<T>): void {
962
1149
  * @throws {TypeError} If the value is not a `Result`.
963
1150
  */
964
1151
  function assertResult<T, E>(r: Result<T, E>): void {
965
- // `Ok` and `Err` must be an object.
966
- if (r == null || typeof r !== 'object' || !(resultKindSymbol in r)) {
1152
+ if (!isResult(r)) {
967
1153
  throw new TypeError(`This(${ r }) is not a Result`);
968
1154
  }
969
1155
  }
@@ -995,4 +1181,29 @@ export function promiseToResult<T, E = Error>(p: Promise<T>): Promise<Result<T,
995
1181
  }).catch((err: E): Result<T, E> => {
996
1182
  return Err(err);
997
1183
  });
1184
+ }
1185
+
1186
+ /**
1187
+ * Checks if a value is an `Option`.
1188
+ *
1189
+ * @typeParam T - The expected type of the value contained within the `Option`.
1190
+ * @param o - The value to be checked as an `Option`.
1191
+ * @returns `true` if the value is an `Option`, otherwise `false`.
1192
+ */
1193
+ export function isOption<T>(o: unknown): o is Option<T> {
1194
+ // `Some` and `None` must be an object.
1195
+ return o != null && typeof o === 'object' && optionKindSymbol in o;
1196
+ }
1197
+
1198
+ /**
1199
+ * Checks if a value is a `Result`.
1200
+ *
1201
+ * @typeParam T - The expected type of the success value contained within the `Result`.
1202
+ * @typeParam E - The expected type of the error value contained within the `Result`.
1203
+ * @param r - The value to be checked as a `Result`.
1204
+ * @returns `true` if the value is a `Result`, otherwise `false`.
1205
+ */
1206
+ export function isResult<T, E>(r: unknown): r is Result<T, E> {
1207
+ // `Ok` and `Err` must be an object.
1208
+ return r != null && typeof r === 'object' && resultKindSymbol in r;
998
1209
  }
package/src/mod.ts CHANGED
@@ -3,6 +3,8 @@ export {
3
3
  None,
4
4
  Ok,
5
5
  Some,
6
+ isOption,
7
+ isResult,
6
8
  promiseToResult,
7
9
  type AsyncIOResult,
8
10
  type AsyncOption,