Allow optional binding to vars

This commit is contained in:
Mark Spanbroek 2021-03-18 09:50:06 +01:00
parent 68153ab182
commit aef59c42eb
4 changed files with 44 additions and 0 deletions

View File

@ -1,4 +1,5 @@
import std/options
import std/macros
import ./chaining
import ./operators
@ -26,6 +27,14 @@ template `=?`*[T](name: untyped{nkIdent}, option: ?T): bool =
template name: T {.used.} = option.unsafeGet()
option.isSome
macro `=?`*[T](variable: untyped{nkVarTy}, option: ?T): bool =
let name = variable[0]
quote do:
var `name` : typeof(`option`.unsafeGet())
if `option`.isSome:
`name` = `option`.unsafeGet()
`option`.isSome
template `|?`*[T](option: ?T, fallback: T): T =
if option.isSome:
option.unsafeGet()

View File

@ -1,3 +1,4 @@
import std/macros
import ./resultsbase
import ./options
import ./operators
@ -41,6 +42,14 @@ template `=?`*[T](name: untyped{nkIdent}, value: ?!T): bool =
template name: T {.used.} = value.unsafeGet()
value.isOk
macro `=?`*[T](variable: untyped{nkVarTy}, option: ?!T): bool =
let name = variable[0]
quote do:
var `name` : typeof(`option`.unsafeGet())
if `option`.isOk:
`name` = `option`.unsafeGet()
`option`.isOk
proc option*[T,E](value: Result[T,E]): ?T =
if value.isOk:
value.unsafeGet.some

View File

@ -74,6 +74,19 @@ suite "optionals":
if a =? a:
check a == 42
test "=? works with var":
if var a =? 1.some and var b =? 2.some:
check a == 1
inc a
check a == b
inc b
check b == 3
else:
fail
if var a =? int.none:
fail
test "unary operator `-` works for options":
check -(-42.some) == 42.some
check -(int.none) == int.none

View File

@ -78,6 +78,19 @@ suite "result":
if a =? a:
check a == 42
test "=? works with var":
if var a =? 1.success and var b =? 2.success:
check a == 1
inc a
check a == b
inc b
check b == 3
else:
fail
if var a =? int.failure(error):
fail
test "catch can be used to convert exceptions to results":
check parseInt("42").catch == 42.success
check parseInt("foo").catch.error of ValueError