Skip to content

Commit

Permalink
feat: support unwrapUnchecked and unwrapErrUnchecked
Browse files Browse the repository at this point in the history
  • Loading branch information
yifanwww committed Sep 11, 2023
1 parent ad4c787 commit f5b6dbf
Show file tree
Hide file tree
Showing 2 changed files with 59 additions and 7 deletions.
46 changes: 39 additions & 7 deletions src/result.class.ts
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,32 @@ export class RustlikeResult<T, E> implements Result<T, E> {
return this.isOk() ? this._value! : op(this._error!);
}

/**
* Returns the contained `Ok` value, without checking that the value is not an `Err`.
*
* **SAFETY**: Calling this method on an `Err` is undefined behavior.
* The safety contract must be upheld by the caller.
*
* ref: https://doc.rust-lang.org/std/result/enum.Result.html#method.unwrap_unchecked
*/
// TODO: find a way to do the check in debug/development mode.
unwrapUnchecked(): T {
return this._value!;
}

/**
* Returns the contained `Err` value, without checking that the value is not an `Ok`.
*
* **SAFETY**: Calling this method on an `Ok` is undefined behavior.
* The safety contract must be upheld by the caller.
*
* ref: https://doc.rust-lang.org/std/result/enum.Result.html#method.unwrap_err_unchecked
*/
// TODO: find a way to do the check in debug/development mode.
unwrapErrUnchecked(): E {
return this._error!;
}

/**
* Returns `res` if itself is `Ok`, otherwise returns the `Err` value of itself.
*
Expand Down Expand Up @@ -278,15 +304,21 @@ export class RustlikeResult<T, E> implements Result<T, E> {
}

private static _equal(self: unknown, other: unknown): boolean {
// TODO: find a better way to check if `self` and `other` is `Result`
// to support user customized `Result` implementation.

const isSelfResult = self instanceof RustlikeResult;
const isOtherResult = other instanceof RustlikeResult;

if (isSelfResult && isOtherResult) {
const isOk = self.isOk();
if (isOk !== other.isOk()) return false;
const _self: Result<unknown, unknown> = self;
const _other: Result<unknown, unknown> = other;

const isOk = _self.isOk();
if (isOk !== _other.isOk()) return false;
return isOk
? RustlikeResult._equal(self._value, other._value)
: RustlikeResult._equal(self._error, other._error);
? RustlikeResult._equal(_self.unwrapUnchecked(), _other.unwrapUnchecked())
: RustlikeResult._equal(_self.unwrapErrUnchecked(), _other.unwrapErrUnchecked());
}

return self === other || (Number.isNaN(self) && Number.isNaN(other));
Expand All @@ -295,11 +327,11 @@ export class RustlikeResult<T, E> implements Result<T, E> {
/**
* Returns `true` if `self` equals to `other`.
*/
equal(other: RustlikeResult<T, E>): boolean {
equal(other: Result<T, E>): boolean {
const isOk = this.isOk();
if (isOk !== other.isOk()) return false;
return isOk
? RustlikeResult._equal(this._value, other._value!)
: RustlikeResult._equal(this._error, other._error!);
? RustlikeResult._equal(this._value, other.unwrapUnchecked())
: RustlikeResult._equal(this._error, other.unwrapErrUnchecked());
}
}
20 changes: 20 additions & 0 deletions src/result.interface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,26 @@ export interface Result<T, E> {
*/
unwrapOrElse(op: (err: E) => T): T;

/**
* Returns the contained `Ok` value, without checking that the value is not an `Err`.
*
* **SAFETY**: Calling this method on an `Err` is undefined behavior.
* The safety contract must be upheld by the caller.
*
* ref: https://doc.rust-lang.org/std/result/enum.Result.html#method.unwrap_unchecked
*/
unwrapUnchecked(): T;

/**
* Returns the contained `Err` value, without checking that the value is not an `Ok`.
*
* **SAFETY**: Calling this method on an `Ok` is undefined behavior.
* The safety contract must be upheld by the caller.
*
* ref: https://doc.rust-lang.org/std/result/enum.Result.html#method.unwrap_err_unchecked
*/
unwrapErrUnchecked(): E;

/**
* Returns `res` if itself is `Ok`, otherwise returns the `Err` value of itself.
*
Expand Down

0 comments on commit f5b6dbf

Please sign in to comment.