-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
8 changed files
with
144 additions
and
80 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,3 @@ | ||
export { Enum, type EnumChecked, pack, match } from "./src/enum"; | ||
export { Enum, pack, match } from "./src/enum"; | ||
export { type Option, Some, None } from "./src/option"; | ||
export { type Result, Ok, Err } from "./src/result"; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,44 +1,12 @@ | ||
// enums are defined as object types, like so: | ||
type Colors = { | ||
Rgb: [number, number, number]; | ||
Raw: string; | ||
}; | ||
import { Enum } from "./src/enum"; | ||
import { Err, Ok, type Result } from "./src/result"; | ||
|
||
// the enum instance type iterates through all keys of the enum, and pulls out the key and type into all possible tuples | ||
type Enum<E> = { [K in keyof E]: [K, E[K]] }[keyof E]; | ||
function mightError(): Result<"Success!", "Error Here!"> { | ||
if (Math.random() > 0.5) { | ||
return Err("Error Here!"); | ||
} | ||
|
||
type ColorsEnum = Enum<Colors>; | ||
// ^? | ||
return Ok("Success!"); | ||
} | ||
|
||
const red: Enum<Colors> = ["Raw", "#fff"]; | ||
const black = ["Rgb", [0, 0, 0]] as Enum<Colors>; | ||
|
||
export const pack = <const E>(...entry: Enum<E>) => entry satisfies Enum<E>; //=> | ||
|
||
const white = pack<Colors>("Raw", ""); | ||
|
||
// type to create the matching arms used in the match function | ||
// "-?" removes any optional parameters, making all cases required | ||
type Arms<E> = { | ||
// biome-ignore lint/suspicious/noExplicitAny: type checking is handled externally | ||
[K in keyof E]-?: (x: E[K]) => any; | ||
}; | ||
|
||
type PartialArms<E, T> = { | ||
[K in keyof E]?: (x: E[K]) => T; | ||
}; | ||
|
||
export const match = <E, Fn extends Arms<E>>( | ||
pattern: Enum<E>, | ||
arms: Fn, | ||
): ReturnType<(typeof arms)[keyof typeof arms]> => | ||
// biome-ignore lint/suspicious/noExplicitAny: required | ||
arms[pattern[0]](pattern[1] as any); | ||
|
||
export const matchPartial = <E, T>( | ||
pattern: Enum<E>, | ||
arms: PartialArms<E, T>, | ||
// biome-ignore lint/suspicious/noExplicitAny: laziness, this can get typed with a union of the arm types | ||
fallback: (x: any) => T, | ||
// biome-ignore lint/suspicious/noExplicitAny: required | ||
): T => ((arms[pattern[0]] as any) || fallback)(pattern[1] as any); | ||
console.log(mightError()); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,28 +1,52 @@ | ||
// enum objects are simply a tuple containing a key and a value which are derived from the enum template E | ||
/** | ||
* Represents an enum object as a tuple containing a key and a value derived from the enum template E. | ||
* @template E - The enum type | ||
*/ | ||
export type Enum<E> = { [K in keyof E]: [K, E[K]] }[keyof E]; | ||
|
||
// type to create the matching arms used in the match function | ||
// "-?" removes any optional parameters, making all cases required | ||
/** | ||
* Defines the structure for matching arms used in the match function. | ||
* All cases are required, unless a default case is provided with `_`. | ||
* @template E - The enum type | ||
*/ | ||
export type Arms<E> = | ||
| { | ||
[K in keyof E]-?: (x: E[K]) => unknown; | ||
} | ||
| ({ | ||
[L in keyof E]?: (x: E[L]) => unknown; | ||
} & { | ||
// make this show only remaining types instead of all types at some point | ||
_: (x: Enum<E>[1]) => unknown; | ||
}); | ||
|
||
// this is a generic way to create enum instances, but the Enum() factory function is preferred | ||
/** | ||
* Creates enum instances. The Enum() factory function is preferred over this method. | ||
* @template E - The enum type | ||
* @param {...Enum<E>} e - The enum entries | ||
* @returns {E} The created enum | ||
*/ | ||
export const pack = <E>(...e: Enum<E>) => e as E; | ||
|
||
/** | ||
* Factory function to create enum instances. | ||
* @template E - The enum type | ||
* @returns {(...e: Enum<E>) => E} A function used to create instances of the enum | ||
*/ | ||
export const Enum = | ||
<E>() => | ||
(...e: Enum<E>) => | ||
e as unknown as E; | ||
|
||
/** | ||
* Matches a pattern against a set of arms and executes the corresponding function. | ||
* @param {E} pattern - The enum to match | ||
* @param {Fn} arms - The object containing matching arms | ||
* @returns {ReturnType<Exclude<Fn[keyof Fn], undefined>>} The result of the matched function | ||
*/ | ||
export const match = <E, Fn extends Arms<E>>(pattern: E, arms: Fn) => | ||
// biome-ignore lint/suspicious/noExplicitAny: return type is handled externally | ||
(((arms as any)[(pattern as any[])[0]] as any) || (arms as any)._)( | ||
// biome-ignore lint/suspicious/noExplicitAny: return type is handled externally | ||
(pattern as any)[1] as unknown, | ||
) as ReturnType<Exclude<(typeof arms)[keyof typeof arms], undefined>>; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,12 +1,46 @@ | ||
import type { Enum } from "./enum"; | ||
import "./unwrap"; | ||
|
||
/** | ||
* Represents a result that can be either Ok(T) or Err(E). | ||
* @template T - The type of the value when the result is Ok | ||
* @template E - The type of the error when the result is Err | ||
* @property {T} Ok - The success value | ||
* @property {E} Err - The error value | ||
*/ | ||
export type Result<T, E> = { | ||
Ok: T; | ||
Err: E; | ||
}; | ||
|
||
/** | ||
* Creates an Ok variant of the Result type, containing a success value. | ||
* @template T - The type of the success value | ||
* @template E - The type of the error (unused in Ok, but needed for type consistency) | ||
* @param {T} ok - The success value to wrap in Ok | ||
* @param {E} [_err] - Optional parameter, ignored in the implementation | ||
* @returns {Result<T, E>} A Result containing the success value | ||
* @example | ||
* const Result = Ok<number, string>(42); | ||
* @remarks | ||
* Generic parameters are required! Make sure they get inferred correctly, | ||
* or set them manually. DO NOT RELY ON FUNCTION RETURN INFERENCE. | ||
*/ | ||
export const Ok = <T, E>(ok: T, _err?: E): Result<T, E> => | ||
["Ok", ok] as unknown as Result<T, E>; | ||
|
||
/** | ||
* Creates an Err variant of the Result type, containing an error value. | ||
* @template T - The type of the success value (unused in Err, but needed for type consistency) | ||
* @template E - The type of the error | ||
* @param {E} err - The error value to wrap in Err | ||
* @param {T} [_ok] - Optional parameter, ignored in the implementation | ||
* @returns {Result<T, E>} A Result containing the error value | ||
* @example | ||
* const errorResult = Err<number, string>("An error occurred"); | ||
* @remarks | ||
* Generic parameters are required! Make sure they get inferred correctly, | ||
* or set them manually. DO NOT RELY ON FUNCTION RETURN INFERENCE. | ||
*/ | ||
export const Err = <T, E>(err: E, _ok?: T): Result<T, E> => | ||
["Err", err] as unknown as Result<T, E>; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters