From f5b6dbfe02da26b51ebf3aafff009c0f038bb3cc Mon Sep 17 00:00:00 2001 From: yifanwww Date: Tue, 12 Sep 2023 01:15:22 +0800 Subject: [PATCH] feat: support unwrapUnchecked and unwrapErrUnchecked --- src/result.class.ts | 46 ++++++++++++++++++++++++++++++++++------- src/result.interface.ts | 20 ++++++++++++++++++ 2 files changed, 59 insertions(+), 7 deletions(-) diff --git a/src/result.class.ts b/src/result.class.ts index 645c7cc..5ec4ccb 100644 --- a/src/result.class.ts +++ b/src/result.class.ts @@ -216,6 +216,32 @@ export class RustlikeResult implements Result { 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. * @@ -278,15 +304,21 @@ export class RustlikeResult implements Result { } 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 = self; + const _other: Result = 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)); @@ -295,11 +327,11 @@ export class RustlikeResult implements Result { /** * Returns `true` if `self` equals to `other`. */ - equal(other: RustlikeResult): boolean { + equal(other: Result): 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()); } } diff --git a/src/result.interface.ts b/src/result.interface.ts index d43e641..0ad9277 100644 --- a/src/result.interface.ts +++ b/src/result.interface.ts @@ -166,6 +166,26 @@ export interface Result { */ 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. *