Makes |?, =? and .option compatible with other types of Result

This commit is contained in:
Mark Spanbroek 2021-04-15 10:54:50 +02:00
parent 83101ce073
commit 89850aab50
2 changed files with 36 additions and 13 deletions

View File

@ -47,25 +47,30 @@ template `->?`*[T,U,V](values: (?!T, ?!U), expression: V): ?!V =
else:
expression.success
template `|?`*[T](value: ?!T, fallback: T): T =
template `|?`*[T,E](value: Result[T,E], fallback: T): T =
value.valueOr(fallback)
template `=?`*[T](name: untyped{nkIdent}, expression: ?!T): bool =
let value = expression
template name: T {.used.} = value.unsafeGet()
value.isSuccess
macro `=?`*[T](variable: untyped{nkVarTy}, expression: ?!T): bool =
let name = variable[0]
macro `=?`*[T,E](name: untyped{nkIdent}, expression: Result[T,E]): bool =
let unsafeGet = bindSym"unsafeGet"
let isOk = bindSym"isOk"
quote do:
let value = `expression`
var `name` : typeof(value.unsafeGet())
if value.isSuccess:
`name` = value.unsafeGet()
value.isSuccess
template `name`: T {.used.} = value.`unsafeGet`()
`isOk`(value)
macro `=?`*[T,E](variable: untyped{nkVarTy}, expression: Result[T,E]): bool =
let name = variable[0]
let unsafeGet = bindSym"unsafeGet"
let isOk = bindSym"isOk"
quote do:
let value = `expression`
var `name` : typeof(value.`unsafeGet`())
if `isOk`(value):
`name` = value.`unsafeGet`()
`isOk`(value)
proc option*[T,E](value: Result[T,E]): ?T =
if value.isSuccess:
if value.isOk:
value.unsafeGet.some
else:
T.none

View File

@ -193,3 +193,21 @@ suite "result":
let converted = works().option
check (converted == @[1, 1, 2, 2, 2].some)
import pkg/questionable/resultsbase
suite "result compatibility":
test "|?, =? and .option work on other types of Result":
type R = Result[int, string]
let good = R.ok 42
let bad = R.err "error"
check bad |? 43 == 43
if value =? good:
check value == 42
else:
fail
check good.option == 42.some