Skip to content

Commit

Permalink
add support for empty ok and err
Browse files Browse the repository at this point in the history
  • Loading branch information
kennethnym committed May 1, 2024
1 parent edc8ab0 commit 1ae5e44
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 9 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "trycat",
"version": "0.2.0",
"version": "0.2.1",
"description": "A lightweight, type-safe, zero-dependency implementation of the Result type.",
"keywords": ["result", "result-type", "error-handling", "error", "monad", "rust", "rust-result"],
"author": "kennethnym",
Expand Down
30 changes: 29 additions & 1 deletion trycat.test.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { describe, expect, expectTypeOf, it, test, vi } from "vitest"
import { type Result, err, ok, tryp, trys } from "./trycat"
import { type Result, err, ok, tryp, trys, Err } from "./trycat"

describe("Ok", () => {
describe("isOk", () => {
Expand All @@ -23,6 +23,11 @@ describe("Ok", () => {
})
})

test("it accepts empty value", () => {
const result = ok()
expect(result.value).toBeUndefined()
})

test("inspect calls the given function with the contained value", () => {
const value = [1, 2, 3]
const fn = vi.fn()
Expand Down Expand Up @@ -142,6 +147,11 @@ describe("Err", () => {
}
})

test("it accepts empty error", () => {
const result = err()
expect(result.error).toBeUndefined()
})

test("inspect does nothing and returns Err", () => {
const fn = vi.fn()
const result = err(401).inspect(fn)
Expand Down Expand Up @@ -250,6 +260,15 @@ describe("trys", () => {
throw new Error("Expected an Err, received an Ok")
}
})

it("works with void function", () => {
const result = trys(() => {})
if (result.isOk()) {
expect(result.value).toBeUndefined()
} else {
throw new Error("Expected an Ok value, received an Err")
}
})
})

describe("tryp", () => {
Expand All @@ -270,4 +289,13 @@ describe("tryp", () => {
throw new Error("Expected an Err, received an Ok")
}
})

it("works with void Promise", async () => {
const result = await tryp(Promise.resolve())
if (result.isOk()) {
expect(result.value).toBeUndefined()
} else {
throw new Error("Expected an Ok value, received an Err")
}
})
})
23 changes: 16 additions & 7 deletions trycat.ts
Original file line number Diff line number Diff line change
Expand Up @@ -324,21 +324,28 @@ class Err<TErr> implements ResultBase<never, TErr> {
*/
type Result<T, TErr> = Ok<T> | Err<TErr>

function ok<T>(value: T): Ok<T> {
return new Ok(value)
function ok(): Ok<void>
function ok<T>(value: T): Ok<T>
function ok<T>(value?: T): Ok<T> | Ok<void> {
return value ? new Ok(value) : new Ok(undefined)
}

function err<TErr>(error: TErr): Err<TErr> {
return new Err(error)
function err(): Err<void>
function err<T>(error: T): Err<T>
function err<TErr>(error?: TErr): Err<TErr> | Err<void> {
return error ? new Err(error) : new Err(undefined)
}

/**
* Calls the given function, catches any thrown error into an {@link Err},
* and wraps the returned value with an {@link Ok} if nothing goes wrong.
*/
function trys<T>(fn: () => T): Result<T, unknown> {
function trys(fn: () => void): Result<void, unknown>
function trys<T>(fn: () => T): Result<T, unknown>
function trys<T>(fn: () => T | undefined): Result<void, unknown> | Result<T, unknown> {
try {
return ok(fn())
const retval = fn()
return retval ? ok(retval) : ok()
} catch (e: unknown) {
return err(e)
}
Expand All @@ -354,7 +361,9 @@ function trys<T>(fn: () => T): Result<T, unknown> {
* return err(res.error)
* }
*/
function tryp<T>(promise: Promise<T>): Promise<Result<T, unknown>> {
function tryp(promise: Promise<void>): Promise<Result<void, unknown>>
function tryp<T>(promise: Promise<T>): Promise<Result<T, unknown>>
function tryp<T>(promise: Promise<T>): Promise<Result<T, unknown> | Result<void, unknown>> {
return promise.then((value) => ok(value)).catch((e) => err(e))
}

Expand Down

0 comments on commit 1ae5e44

Please sign in to comment.