mirror of
https://github.com/logos-storage/questionable.git
synced 2026-01-11 18:23:13 +00:00
Compare commits
No commits in common. "main" and "0.10.13" have entirely different histories.
@ -12,7 +12,7 @@ Use the [Nimble][3] package manager to add `questionable` to an existing
|
|||||||
project. Add the following to its .nimble file:
|
project. Add the following to its .nimble file:
|
||||||
|
|
||||||
```nim
|
```nim
|
||||||
requires "questionable >= 0.10.15 & < 0.11.0"
|
requires "questionable >= 0.10.13 & < 0.11.0"
|
||||||
```
|
```
|
||||||
|
|
||||||
If you want to make use of Result types, then you also have to add either the
|
If you want to make use of Result types, then you also have to add either the
|
||||||
@ -151,7 +151,7 @@ have to explicitly import the `questionable/results` module:
|
|||||||
import questionable/results
|
import questionable/results
|
||||||
```
|
```
|
||||||
|
|
||||||
You can use `?!` to make a Result type. These Result types either hold a value or
|
You can use `?!` make a Result type. These Result types either hold a value or
|
||||||
an error. For example the type `?!int` is short for `Result[int, ref
|
an error. For example the type `?!int` is short for `Result[int, ref
|
||||||
CatchableError]`.
|
CatchableError]`.
|
||||||
|
|
||||||
@ -226,7 +226,6 @@ Any Result can be converted to an Option:
|
|||||||
|
|
||||||
```nim
|
```nim
|
||||||
let converted = works().option # equals @[1, 1, 2, 2, 2].some
|
let converted = works().option # equals @[1, 1, 2, 2, 2].some
|
||||||
let errOption = fails().errorOption # option that is set when the Result holds an error
|
|
||||||
```
|
```
|
||||||
|
|
||||||
[1]: https://nim-lang.org/docs/options.html
|
[1]: https://nim-lang.org/docs/options.html
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
version = "0.10.15"
|
version = "0.10.13"
|
||||||
author = "Questionable Authors"
|
author = "Questionable Authors"
|
||||||
description = "Elegant optional types"
|
description = "Elegant optional types"
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
|
|||||||
@ -11,28 +11,26 @@ macro captureBindError*(error: var ref CatchableError, expression): auto =
|
|||||||
|
|
||||||
# name of the error variable as a string literal
|
# name of the error variable as a string literal
|
||||||
let errorVariableName = newLit($error)
|
let errorVariableName = newLit($error)
|
||||||
|
|
||||||
let evaluated = genSym(nskLet, "evaluated")
|
|
||||||
quote do:
|
quote do:
|
||||||
# add error variable to the top of the stack
|
# add error variable to the top of the stack
|
||||||
static: errorVariableNames.add(`errorVariableName`)
|
static: errorVariableNames.add(`errorVariableName`)
|
||||||
# evaluate the expression
|
# evaluate the expression
|
||||||
let `evaluated` = `expression`
|
let evaluated = `expression`
|
||||||
# pop error variable from the stack
|
# pop error variable from the stack
|
||||||
static: discard errorVariableNames.pop()
|
static: discard errorVariableNames.pop()
|
||||||
# return the evaluated result
|
# return the evaluated result
|
||||||
`evaluated`
|
evaluated
|
||||||
|
|
||||||
func unsafeCatchableError[T](_: Option[T]): ref CatchableError =
|
func error[T](_: Option[T]): ref CatchableError =
|
||||||
newException(ValueError, "Option is set to `none`")
|
newException(ValueError, "Option is set to `none`")
|
||||||
|
|
||||||
func unsafeCatchableError[T](_: ref T): ref CatchableError =
|
func error[T](_: ref T): ref CatchableError =
|
||||||
newException(ValueError, "ref is nil")
|
newException(ValueError, "ref is nil")
|
||||||
|
|
||||||
func unsafeCatchableError[T](_: ptr T): ref CatchableError =
|
func error[T](_: ptr T): ref CatchableError =
|
||||||
newException(ValueError, "ptr is nil")
|
newException(ValueError, "ptr is nil")
|
||||||
|
|
||||||
func unsafeCatchableError[Proc: proc | iterator](_: Proc): ref CatchableError =
|
func error[Proc: proc | iterator](_: Proc): ref CatchableError =
|
||||||
newException(ValueError, "proc or iterator is nil")
|
newException(ValueError, "proc or iterator is nil")
|
||||||
|
|
||||||
macro bindFailed*(expression: typed) =
|
macro bindFailed*(expression: typed) =
|
||||||
@ -51,4 +49,4 @@ macro bindFailed*(expression: typed) =
|
|||||||
# check that the error variable is in scope
|
# check that the error variable is in scope
|
||||||
when compiles(`errorVariable`):
|
when compiles(`errorVariable`):
|
||||||
# assign bind error to error variable
|
# assign bind error to error variable
|
||||||
`errorVariable` = `expression`.unsafeCatchableError
|
`errorVariable` = `expression`.error
|
||||||
|
|||||||
@ -123,18 +123,6 @@ template toOption*[T, E](value: Result[T, E]): ?T =
|
|||||||
|
|
||||||
value.option
|
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 =
|
proc errorOption*[T, E](value: Result[T, E]): ?E =
|
||||||
## Returns an Option that contains the error from the Result, if it has one.
|
## Returns an Option that contains the error from the Result, if it has one.
|
||||||
|
|
||||||
|
|||||||
@ -643,19 +643,6 @@ suite "result":
|
|||||||
someProc(42.success)
|
someProc(42.success)
|
||||||
someProc(int.failure "some error")
|
someProc(int.failure "some error")
|
||||||
|
|
||||||
type TypeWithSideEffect = object
|
|
||||||
proc `$`*(value: TypeWithSideEffect): string {.sideEffect.} =
|
|
||||||
discard
|
|
||||||
|
|
||||||
suite "result side effects":
|
|
||||||
|
|
||||||
test "without statement with error works when `$` has side effects":
|
|
||||||
proc foo =
|
|
||||||
without x =? TypeWithSideEffect.failure("error"), error:
|
|
||||||
discard error
|
|
||||||
return
|
|
||||||
fail()
|
|
||||||
foo()
|
|
||||||
|
|
||||||
import pkg/questionable/resultsbase
|
import pkg/questionable/resultsbase
|
||||||
|
|
||||||
@ -663,7 +650,7 @@ suite "result compatibility":
|
|||||||
|
|
||||||
type R = Result[int, string]
|
type R = Result[int, string]
|
||||||
let good = R.ok 42
|
let good = R.ok 42
|
||||||
let bad = R.err "some error"
|
let bad = R.err "error"
|
||||||
|
|
||||||
test "|?, =? and .option work on other types of Result":
|
test "|?, =? and .option work on other types of Result":
|
||||||
check bad |? 43 == 43
|
check bad |? 43 == 43
|
||||||
@ -681,13 +668,3 @@ suite "result compatibility":
|
|||||||
fail
|
fail
|
||||||
without b =? good:
|
without b =? good:
|
||||||
fail
|
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"
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user