import { Option } from './option.js' enum ResultType { Ok , Err } export class Result { private value?: T private error?: E private constructor(type: ResultType.Ok, value: T) private constructor(type: ResultType.Err, error: E) private constructor(private type: ResultType, valueOrError: T | E) { if (type === ResultType.Ok) { this.value = valueOrError as T } else { this.error = valueOrError as E } } static Ok(value: T): Result { return new Result(ResultType.Ok, value) } static Err(error: E): Result { return new Result(ResultType.Err, error) } isOk() { return this.type === ResultType.Ok } isErr() { return this.type === ResultType.Err } map(mapper: (val: T) => U): Result { if (this.isOk()) { return Result.Ok(mapper(this.value!)) } else { return Result.Err(this.error!) } } mapErr(mapper: (err: E) => U): Result { if (this.isOk()) { return Result.Ok(this.value!) } else { return Result.Err(mapper(this.error!)) } } mapOr(defaultValue: U, mapper: (val: T) => U): U { if (this.isOk()) { return mapper(this.value!) } else { return defaultValue } } mapOrElse(createDefaultValue: (err: E) => U, mapper: (val: T) => U): U { if (this.isOk()) { return mapper(this.value!) } else { return createDefaultValue(this.error!) } } /** * @throws {E} */ unwrap(): T { if (this.isOk()) { return this.value! } else { throw this.error! } } unwrapOr(defaultValue: U): T | U { if (this.isOk()) { return this.value! } else { return defaultValue } } unwrapOrElse(createDefaultValue: (err: E) => U): T | U { if (this.isOk()) { return this.value! } else { return createDefaultValue(this.error!) } } /** * @throws {Error} */ unwrapErr(): E { if (this.isErr()) { return this.error! } else { throw new Error('unwrapErr called on a Ok') } } /** * @throws {Error} */ expect(message: string): T { if (this.isOk()) { return this.value! } else { throw new Error(message, { cause: this.error! }) } } /** * @throws {Error} */ expectErr(message: string): E { if (this.isErr()) { return this.error! } else { throw new Error(message, { cause: this.value! }) } } ok(): Option { if (this.isOk()) { return Option.Some(this.value!) } else { return Option.None() } } err(): Option { if (this.isOk()) { return Option.None() } else { return Option.Some(this.error!) } } }