@rustable/enum
Version:
Rust-inspired pattern matching and type-safe error handling for TypeScript. Includes Option<T> for null-safety and Result<T, E> for error handling, with comprehensive pattern matching support
257 lines (253 loc) • 6.69 kB
JavaScript
var _enum = require('./enum.js');
var option = require('./option.js');
;
class Result extends _enum.Enum {
static Ok(value) {
return new Result("Ok", value);
}
static Err(error) {
return new Result("Err", error);
}
/**
* Checks if the Result is Ok
* @returns True if Ok, false if Err
*
* @example
* ```typescript
* const result = Ok(5);
* if (result.isOk()) {
* console.log("Operation succeeded");
* }
* ```
*/
isOk() {
return this.is("Ok");
}
/**
* Checks if the Result is Err
* @returns True if Err, false if Ok
*
* @example
* ```typescript
* const result = Err(new Error("Failed"));
* if (result.isErr()) {
* console.log("Operation failed");
* }
* ```
*/
isErr() {
return this.is("Err");
}
/**
* Converts to Option<T>, Some(t) if Ok(t), None if Err
* @returns Option<T> representation of the Result
*/
ok() {
return this.isOk() ? option.Some(super.unwrap()) : option.None;
}
/**
* Converts to Option<E>, Some(e) if Err(e), None if Ok
* @returns Option<E> representation of the Result
*/
err() {
return this.isErr() ? option.Some(super.unwrap()) : option.None;
}
/**
* Returns the Ok value or throws if Err
* @throws Error if the Result is Err
* @returns T Ok value
*/
unwrap() {
if (this.isOk()) {
return super.unwrap();
}
throw super.unwrap();
}
/**
* Returns the Ok value or the provided default
* @param def Default value to return if Err
* @returns T Ok value or default
*/
unwrapOr(def) {
return this.isOk() ? super.unwrap() : def;
}
/**
* Returns the Ok value or computes it from the error
* @param fn Function to compute the Ok value from the error
* @returns T Ok value or computed value
*/
unwrapOrElse(fn) {
return this.isOk() ? super.unwrap() : fn(super.unwrap());
}
/**
* Returns the Ok value or throws the error if Err
* @throws Error if the Result is Err
* @returns T Ok value
*/
unwrapOrThrow() {
if (this.isOk())
return super.unwrap();
throw super.unwrap();
}
/**
* Returns the Err value or throws if Ok
* @throws Error if the Result is Ok
* @returns E Err value
*/
unwrapErr() {
if (this.isErr())
return super.unwrap();
throw new ReferenceError("Cannot unwrap Err value of Result.Ok");
}
/**
* Pattern matches on the Result
* @param fn Match handlers for Ok and Err values
* @returns Result of matching the Result
*/
match(fn) {
return super.match(fn);
}
/**
* Maps the Ok value using the provided function
* @param fn Function to map the Ok value
* @returns Result<U, E> mapped Result
*/
map(fn) {
return this.isOk() ? Result.Ok(fn(super.unwrap())) : Result.Err(super.unwrap());
}
/**
* Maps the Ok value using the provided function, or returns the default value if Err
* @param defaultValue Default value to return if Err
* @param fn Function to map the Ok value
* @returns U mapped value or default
*/
mapOr(defaultValue, fn) {
return this.isOk() ? fn(super.unwrap()) : defaultValue;
}
/**
* Maps the Err value using the provided function
* @param fn Function to map the Err value
* @returns Result<T, U> mapped Result
*/
mapErr(fn) {
return this.isOk() ? Result.Ok(super.unwrap()) : Result.Err(fn(super.unwrap()));
}
/**
* Throws an error if the Result is Err
* @param msg Error message to include in the error
* @returns T Ok value
*/
expect(msg) {
if (this.isOk())
return super.unwrap();
throw new Error(`${msg}: ${super.unwrap()}`);
}
/**
* Chained Result-returning functions
* @param res Result to chain
* @returns Result<U, E> chained Result
*/
and(res) {
return this.isOk() ? res : Result.Err(super.unwrap());
}
/**
* Chain Result-returning functions
* @param op Function to chain
* @returns Result<U, E> chained Result
*/
andThen(op) {
return this.isOk() ? op(super.unwrap()) : Result.Err(super.unwrap());
}
/**
* Chained Result-returning functions
* @param res Result to chain
* @returns Result<T, F> chained Result
*/
or(res) {
return this.isOk() ? Result.Ok(super.unwrap()) : res;
}
/**
* Returns this Result if Ok, or computes a new Result if Err
* @param fn Function to compute a new Result if Err
* @returns Result<T, E> or Result<U, E> computed Result
*/
orElse(fn) {
return this.isOk() ? Result.Ok(super.unwrap()) : fn(super.unwrap());
}
/**
* Wraps a Promise into a Result, converting successful resolution to Ok and rejection to Err
* @template T Type of the success value
* @template E Type of the error value, must extend Error
* @param promise Promise to wrap
* @returns Promise<Result<T, E>> A promise that resolves to a Result
*
* @example
* ```typescript
* // Wrap a promise that might fail
* const result = await Result.fromPromise<string, Error>(
* fetch('https://api.example.com/data')
* .then(res => res.text())
* );
*
* // Handle the result
* if (result.isOk()) {
* console.log('Got data:', result.unwrap());
* } else {
* console.error('Failed:', result.unwrapErr().message);
* }
* ```
*/
static async fromAsync(promise) {
try {
const value = await promise;
return Result.Ok(value);
} catch (error) {
return Result.Err(error);
}
}
/**
* Wraps a function in a Result, converting successful execution to Ok and thrown errors to Err
* @template T Type of the return value
* @template E Type of the error value, must extend Error
* @template Args Type of the function arguments
* @param fn Function to wrap
* @returns A function that returns Result<T, E>
*
* @example
* ```typescript
* const parseJSON = Result.fromFn<any, Error, [string]>(JSON.parse);
*
* // Success case
* const result1 = parseJSON('{"key": "value"}');
* if (result1.isOk()) {
* console.log('Parsed:', result1.unwrap());
* }
*
* // Error case
* const result2 = parseJSON('invalid json');
* if (result2.isErr()) {
* console.error('Parse failed:', result2.unwrapErr().message);
* }
* ```
*/
static fromFn(fn) {
return (...args) => {
try {
const value = fn(...args);
return Result.Ok(value);
} catch (error) {
return Result.Err(error);
}
};
}
}
function Ok(val) {
return Result.Ok(val);
}
function Err(err) {
return Result.Err(err);
}
exports.Err = Err;
exports.Ok = Ok;
exports.Result = Result;
;