Adds results.Opt

It turned out that Nim's Option type is broken for `not nil` and
`requiresInit` types. It will report an udesired warning due to
the way `none` is defined. The `Result` type doesn't suffer from
this problem, so I've transitioned some APIs in NBC to use the
new `results.Opt[T]` type (alias of `Result[T, void]`).

Perhaps we should renamed `Result` to `Res` to make the naming
more consistent and to allow the code to more easily fit in the
80 character per-line budget.
This commit is contained in:
Zahary Karadjov 2020-04-22 15:43:26 +03:00
parent 9a0cded592
commit 4acc3866ed
No known key found for this signature in database
GPG Key ID: C8936F8A3073D609
1 changed files with 26 additions and 1 deletions

View File

@ -254,6 +254,8 @@ type
of true:
v: T
Opt*[T] = Result[T, void]
func raiseResultError[T, E](self: Result[T, E]) {.noreturn, noinline.} =
# noinline because raising should take as little space as possible at call
# site
@ -272,12 +274,19 @@ func raiseResultError[T, E](self: Result[T, E]) {.noreturn, noinline.} =
raise (res ResultError[E])(msg: "Trying to access value with err", error: self.e)
func raiseResultDefect(m: string, v: auto) {.noreturn, noinline.} =
mixin `$`
when compiles($v): raise (ref ResultDefect)(msg: m & ": " & $v)
else: raise (ref ResultDefect)(msg: m)
func raiseResultDefect(m: string) {.noreturn, noinline.} =
raise (ref ResultDefect)(msg: m)
template assertOk(self: Result) =
if not self.o:
raiseResultDefect("Trying to acces value with err Result", self.e)
when self.E isnot void:
raiseResultDefect("Trying to acces value with err Result", self.e)
else:
raiseResultDefect("Trying to acces value with err Result")
template ok*[T, E](R: type Result[T, E], x: auto): R =
## Initialize a result with a success and value
@ -294,17 +303,33 @@ template err*[T, E](R: type Result[T, E], x: auto): R =
## Example: `Result[int, string].err("uh-oh")`
R(o: false, e: x)
template err*[T](R: type Result[T, void]): R =
R(o: false)
template err*[T, E](self: var Result[T, E], x: auto) =
## Set the result as an error
## Example: `result.err("uh-oh")`
self = err(type self, x)
template err*[T](self: var Result[T, void]) =
## Set the result as an error
## Example: `result.err()`
self = err(type self)
template ok*(v: auto): auto = ok(typeof(result), v)
template err*(v: auto): auto = err(typeof(result), v)
template isOk*(self: Result): bool = self.o
template isErr*(self: Result): bool = not self.o
template isSome*(o: Opt): bool =
## Alias for `isOk`
isOk o
template isNone*(o: Opt): bool =
## Alias of `isErr`
isErr o
func map*[T, E, A](
self: Result[T, E], f: proc(x: T): A): Result[A, E] {.inline.} =
## Transform value using f, or return error