Skip to main content

latest

tsrs - a typescript library that emulates rust's Result and Option types

Works with
This package works with Bun
This package works with Cloudflare Workers
This package works with Node.js
This package works with Deno
This package works with Browsers
JSR Score
94%
Published
2 months ago (0.0.2)
rootmod.ts
/** * tsrs - a typescript library that emulates rust's Result and Option types * @module */ /** Represents an error value */ type Err<E> = { _type: "Err"; err: E }; /** Represents a successful value */ type Ok<T> = { _type: "Ok"; value: T }; /** Result is a type that represents either success (Ok) or failure (Err). */ export class Result<T, E> { /** * Constructs an Ok result. * @param value The value to wrap. * @returns An Ok result. */ static #ok = <T>(value: T): Ok<T> => ({ _type: "Ok", value: value }); /** * Constructs an Err result. * @param err The error value to wrap. * @returns An Err result. */ static #err = <T>(err: T): Err<T> => ({ _type: "Err", err: err }); #inner: Ok<T> | Err<E>; /** * Constructs a new Result instance. * @private * @param t The inner value representing either Ok or Err. */ private constructor(t: Ok<T> | Err<E>) { this.#inner = t; } /** * Creates a new Result from a function that can throw. * @param fn A function that can throw. * @param err An error message / type for when unwrapping. * @returns A Result containing either the function result or the error value. */ static fromThrow<U, V>(fn: () => U, err: V): Result<U, V> { try { return new Result(Result.#ok(fn())); } catch (_) { return new Result(Result.#err(err)); } } /** * Creates a new Result from a Promise. * @param p A Promise that resolves to a value or rejects with an error. * @returns A Promise resolving to a Result containing either the resolved value or the error. */ static async fromPromise<T>(p: Promise<T>): Promise<Result<T, unknown>> { try { const v = await p; return new Result(Result.#ok(v)); } catch (e) { return new Result(Result.#err(e as unknown)); } } /** * Checks if the result is Ok. * @returns True if the result is Ok, otherwise false. */ is_ok(): boolean { return this.#inner._type === "Ok"; } /** * Checks if the result is Err. * @returns True if the result is Err, otherwise false. */ is_err(): boolean { return !this.is_ok(); } /** * Unwraps the Ok value. * @throws Error if the result is Err. * @returns The unwrapped Ok value. */ unwrap(): T { if (this.#inner._type === "Err") { throw new Error("Tried to unwrap Err value: " + this.#inner.err); } return this.#inner.value; } /** * Unwraps the Ok value or returns a fallback value. * @param fallback The fallback value to return if the result is Err. * @returns The unwrapped Ok value if present, otherwise the fallback value. */ unwrapOr(fallback: T): T { if (this.#inner._type === "Ok") { return this.#inner.value; } else { return fallback; } } /** * Unwraps the Ok value or computes a fallback value by invoking a function. * @param cb A function to invoke to compute the fallback value. * @returns The unwrapped Ok value if present, otherwise the computed fallback value. */ unwrapOrElse(cb: () => T): T { if (this.#inner._type === "Ok") { return this.#inner.value; } else { return cb(); } } /** * Unwraps the Ok value or throws an error with a custom message. * @param message The error message to use if the result is Err. * @throws Error with the specified message if the result is Err. * @returns The unwrapped Ok value. */ expect(message: string): T { if (this.#inner._type === "Ok") { return this.#inner.value; } else { throw new Error(message); } } /** * Converts the Result to an Option. * @returns Some value if Ok, None if Err. */ ok(): Option<T> { return Option.fromResult<T, E>(this); } match<U>(okCallback: (value: T) => U, errCallback: (err: E) => U): U { if (this.#inner._type === "Ok") { return okCallback(this.#inner.value); } else { return errCallback(this.#inner.err); } } } /** Represents a None value */ type None = { _type: "None" }; /** Represents a Some value */ type Some<T> = { _type: "Some"; value: T }; /** Represents an optional value */ export class Option<T> { /** Represents a None value */ static none: None = { _type: "None" }; /** * Constructs a Some value. * @param value The value to wrap. * @returns A Some value containing the specified value. */ static some = <T>(value: T): Some<T> => ({ _type: "Some", value: value }); #inner: Some<T> | None; /** * Constructs a new Option instance. * @private * @param t The inner value representing either Some or None. */ private constructor(t: None | Some<T>) { this.#inner = t; } /** * Creates an Option from a function that can throw. * @param fn A function that can throw. * @returns Some value if the function succeeds, None if it throws an error. */ static fromThrow<T>(fn: () => T): Option<T> { try { return new Option(Option.some(fn())); } catch (_) { return new Option(Option.none); } } /** * Creates an Option from a Result. * @param result The Result to convert. * @returns Some value if the Result is Ok, None if it is Err. */ static fromResult<U, E>(result: Result<U, E>): Option<U> { if (result.is_ok()) { return new Option<U>(Option.some(result.unwrap())); } else { return new Option<U>(Option.none); } } /** * Checks if the option is Some. * @returns True if the option is Some, otherwise false. */ is_some(): boolean { return this.#inner._type === "Some"; } /** * Checks if the option is None. * @returns True if the option is None, otherwise false. */ is_none(): boolean { return !this.is_some(); } /** * Unwraps the Some value. * @throws Error if the option is None. * @returns The unwrapped Some value. */ unwrap(): T { if (this.#inner._type === "None") { throw new Error("Tried to unwrap None value."); } return this.#inner.value; } /** * Unwraps the Some value or returns a fallback value. * @param value The fallback value to return if the option is None. * @returns The unwrapped Some value if present, otherwise the fallback value. */ unwrapOr(value: T): T { if (this.#inner._type === "Some") { return this.#inner.value; } else { return value; } } /** * Unwraps the Some value or computes a fallback value by invoking a function. * @param cb A function to invoke to compute the fallback value. * @returns The unwrapped Some value if present, otherwise the computed fallback value. */ unwrapOrElse(cb: () => T): T { if (this.#inner._type === "Some") { return this.#inner.value; } else { return cb(); } } /** * Unwraps the Some value or throws an error with a custom message. * @param message The error message to use if the option is None. * @throws Error with the specified message if the option is None. * @returns The unwrapped Some value. */ expect(message: string): T { if (this.#inner._type === "Some") { return this.#inner.value; } else { throw new Error(message); } } }