Skip to content

Commit

Permalink
without with error variable works for any Result type
Browse files Browse the repository at this point in the history
  • Loading branch information
markspanbroek committed Mar 12, 2024
1 parent 83ae4a6 commit af4bbfb
Show file tree
Hide file tree
Showing 3 changed files with 28 additions and 6 deletions.
10 changes: 5 additions & 5 deletions questionable/private/binderror.nim
Original file line number Diff line number Diff line change
Expand Up @@ -21,16 +21,16 @@ macro captureBindError*(error: var ref CatchableError, expression): auto =
# return the evaluated result
evaluated

func unsafeError[T](_: Option[T]): ref CatchableError =
func unsafeCatchableError[T](_: Option[T]): ref CatchableError =
newException(ValueError, "Option is set to `none`")

func unsafeError[T](_: ref T): ref CatchableError =
func unsafeCatchableError[T](_: ref T): ref CatchableError =
newException(ValueError, "ref is nil")

func unsafeError[T](_: ptr T): ref CatchableError =
func unsafeCatchableError[T](_: ptr T): ref CatchableError =
newException(ValueError, "ptr is nil")

func unsafeError[Proc: proc | iterator](_: Proc): ref CatchableError =
func unsafeCatchableError[Proc: proc | iterator](_: Proc): ref CatchableError =
newException(ValueError, "proc or iterator is nil")

macro bindFailed*(expression: typed) =
Expand All @@ -49,4 +49,4 @@ macro bindFailed*(expression: typed) =
# check that the error variable is in scope
when compiles(`errorVariable`):
# assign bind error to error variable
`errorVariable` = `expression`.unsafeError
`errorVariable` = `expression`.unsafeCatchableError
12 changes: 12 additions & 0 deletions questionable/results.nim
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,18 @@ template toOption*[T, E](value: Result[T, E]): ?T =

value.option

proc unsafeCatchableError*[T, E](value: Result[T, E]): ref CatchableError =
## Returns the error from the Result, converted to `ref CatchableError` if
## necessary. Behaviour is undefined when the result holds a value instead of
## an error.
when E is ref CatchableError:
value.unsafeError
else:
when compiles($value.unsafeError):
newException(ResultFailure, $value.unsafeError)
else:
newException(ResultFailure, "Result is an error")

proc errorOption*[T, E](value: Result[T, E]): ?E =
## Returns an Option that contains the error from the Result, if it has one.

Expand Down
12 changes: 11 additions & 1 deletion testmodules/results/test.nim
Original file line number Diff line number Diff line change
Expand Up @@ -663,7 +663,7 @@ suite "result compatibility":

type R = Result[int, string]
let good = R.ok 42
let bad = R.err "error"
let bad = R.err "some error"

test "|?, =? and .option work on other types of Result":
check bad |? 43 == 43
Expand All @@ -681,3 +681,13 @@ suite "result compatibility":
fail
without b =? good:
fail

test "without statement with error works on other type of Result":
without value =? bad, error:
check error of ResultFailure
check error.msg == "some error"

test "without statement with error works on Result[T, void]":
without value =? Result[int, void].err, error:
check error of ResultFailure
check error.msg == "Result is an error"

0 comments on commit af4bbfb

Please sign in to comment.