From fc088568beb892807e4996b1d8531a8e3ca34fae Mon Sep 17 00:00:00 2001 From: CRIMX Date: Wed, 13 Nov 2024 09:57:38 +0800 Subject: [PATCH] feat(option): add option static unwrapOr --- src/option.ts | 13 +++++++++++++ src/result.ts | 2 ++ test/option.test.ts | 22 ++++++++++++++++++---- 3 files changed, 33 insertions(+), 4 deletions(-) diff --git a/src/option.ts b/src/option.ts index 9aaa323..0a7b13b 100644 --- a/src/option.ts +++ b/src/option.ts @@ -89,6 +89,17 @@ export class Option { : false; } + /** + * @returns the `unwrapOr()` result if the value is an `Option`, otherwise the value itself. + * + * @param valueOrOption - A value of type `T` or an `Option` + */ + public static unwrapOr(valueOrOption: T | Option): T | undefined { + return Option.isOption(valueOrOption) + ? valueOrOption.unwrapOr() + : valueOrOption; + } + private readonly [SPECIES] = SPECIES_OPTION; private readonly _value: T; @@ -346,6 +357,8 @@ export class Option { /** * @returns the contained `Some` value or `undefined` otherwise. + * + * Arguments passed to `unwrapOr` are eagerly evaluated; if you are passing the result of a function call, it is recommended to use `unwrapOrElse`, which is lazily evaluated. */ public unwrapOr(): T | undefined; /** diff --git a/src/result.ts b/src/result.ts index 34f0bb5..5afd78e 100644 --- a/src/result.ts +++ b/src/result.ts @@ -361,6 +361,8 @@ export class Result { /** * @returns the contained `Err` error or `undefined` otherwise. + * + * Arguments passed to `unwrapErrOr` are eagerly evaluated; if you are passing the result of a function call, it is recommended to use `unwrapErrOrElse`, which is lazily evaluated. */ public unwrapErrOr(): E | undefined; /** diff --git a/test/option.test.ts b/test/option.test.ts index 6a0c04e..2bcd76a 100644 --- a/test/option.test.ts +++ b/test/option.test.ts @@ -3,7 +3,7 @@ import { describe, it, expect, vi } from "vitest"; import { Option, Some, None, Err, Ok } from "../src"; describe("Option", () => { - describe("Some", () => { + describe("Option.Some", () => { it("creates a Some with a value", () => { const some = Some("hello"); expect(some.isSome()).toBe(true); @@ -11,14 +11,14 @@ describe("Option", () => { }); }); - describe("None", () => { + describe("Option.None", () => { it("creates a None", () => { expect(None.isNone()).toBe(true); expect(() => None.unwrap()).toThrow(); }); }); - describe("from", () => { + describe("Option.from", () => { it("creates a Some for a truthy value", () => { const some = Option.from("hello"); expect(some.isSome()).toBe(true); @@ -42,7 +42,7 @@ describe("Option", () => { }); }); - describe("isSame", () => { + describe("Option.isSame", () => { it("returns true if both are the same Some value", () => { const result = Option.isSame(Some("a"), Some("a")); expect(result).toBe(true); @@ -73,6 +73,20 @@ describe("Option", () => { }); }); + describe("Option.unwrapOr", () => { + it("returns the value for a Some", () => { + expect(Option.unwrapOr(Some("hello"))).toBe("hello"); + }); + + it("returns the value if the value if not an Option", () => { + expect(Option.unwrapOr("hello")).toBe("hello"); + }); + + it("returns undefined for a None", () => { + expect(None.unwrapOr("world")).toBe("world"); + }); + }); + describe("isSome", () => { it("returns true for a Some", () => { const some = Some("hello");