(Init): Added shit
This commit is contained in:
75
crates/shared/src/util/result.ts
Normal file
75
crates/shared/src/util/result.ts
Normal file
@@ -0,0 +1,75 @@
|
||||
/**
|
||||
* Result<T, E> — a lightweight, framework-agnostic result type used across
|
||||
* `@elly/shared`, `@elly/core`, and `@elly/bot`.
|
||||
*
|
||||
* Prefer this over throwing for expected/recoverable failures crossing
|
||||
* module or IPC boundaries. Reserve exceptions for genuinely exceptional
|
||||
* conditions (programmer error, invariant violation, infrastructure failure).
|
||||
*/
|
||||
|
||||
export type Ok<T> = { readonly ok: true; readonly value: T };
|
||||
export type Err<E> = { readonly ok: false; readonly error: E };
|
||||
export type Result<T, E = Error> = Ok<T> | Err<E>;
|
||||
|
||||
export function ok<T>(value: T): Ok<T> {
|
||||
return { ok: true, value };
|
||||
}
|
||||
|
||||
export function err<E>(error: E): Err<E> {
|
||||
return { ok: false, error };
|
||||
}
|
||||
|
||||
export function isOk<T, E>(result: Result<T, E>): result is Ok<T> {
|
||||
return result.ok;
|
||||
}
|
||||
|
||||
export function isErr<T, E>(result: Result<T, E>): result is Err<E> {
|
||||
return !result.ok;
|
||||
}
|
||||
|
||||
/**
|
||||
* Unwrap a Result or throw the error. Use sparingly — defeats the purpose of
|
||||
* Result in most call sites.
|
||||
*/
|
||||
export function unwrap<T, E>(result: Result<T, E>): T {
|
||||
if (result.ok) return result.value;
|
||||
throw result.error instanceof Error
|
||||
? result.error
|
||||
: new Error(`Result.unwrap on Err: ${String(result.error)}`);
|
||||
}
|
||||
|
||||
/**
|
||||
* Map the success value of a Result without affecting the error branch.
|
||||
*/
|
||||
export function map<T, U, E>(result: Result<T, E>, fn: (value: T) => U): Result<U, E> {
|
||||
return result.ok ? ok(fn(result.value)) : result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Map the error value of a Result without affecting the success branch.
|
||||
*/
|
||||
export function mapErr<T, E, F>(result: Result<T, E>, fn: (error: E) => F): Result<T, F> {
|
||||
return result.ok ? result : err(fn(result.error));
|
||||
}
|
||||
|
||||
/**
|
||||
* Wrap a throwing synchronous function in a Result.
|
||||
*/
|
||||
export function tryCatch<T>(fn: () => T): Result<T, Error> {
|
||||
try {
|
||||
return ok(fn());
|
||||
} catch (e) {
|
||||
return err(e instanceof Error ? e : new Error(String(e)));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Wrap a throwing async function in a Result.
|
||||
*/
|
||||
export async function tryCatchAsync<T>(fn: () => Promise<T>): Promise<Result<T, Error>> {
|
||||
try {
|
||||
return ok(await fn());
|
||||
} catch (e) {
|
||||
return err(e instanceof Error ? e : new Error(String(e)));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user