2021-05-06 17:12:52 +02:00
|
|
|
import std/options
|
|
|
|
|
import std/macros
|
|
|
|
|
|
|
|
|
|
proc option[T](option: Option[T]): Option[T] =
|
|
|
|
|
option
|
|
|
|
|
|
2021-12-04 17:26:08 +01:00
|
|
|
proc placeholder(T: type): T =
|
|
|
|
|
discard
|
|
|
|
|
|
2021-05-06 17:12:52 +02:00
|
|
|
template bindLet(name, expression): bool =
|
|
|
|
|
let option = expression.option
|
2021-12-04 17:26:08 +01:00
|
|
|
type T = typeof(option.unsafeGet())
|
|
|
|
|
let name {.used.} = if option.isSome: option.unsafeGet() else: placeholder(T)
|
2021-05-06 17:12:52 +02:00
|
|
|
option.isSome
|
|
|
|
|
|
|
|
|
|
template bindVar(name, expression): bool =
|
|
|
|
|
let option = expression.option
|
2021-12-04 17:26:08 +01:00
|
|
|
type T = typeof(option.unsafeGet())
|
|
|
|
|
var name {.used.} : T = placeholder(T)
|
2021-05-06 17:12:52 +02:00
|
|
|
if option.isSome:
|
|
|
|
|
name = option.unsafeGet()
|
|
|
|
|
option.isSome
|
|
|
|
|
|
|
|
|
|
macro `=?`*(name, expression): bool =
|
2021-06-04 17:34:48 +02:00
|
|
|
## The `=?` operator lets you bind the value inside an Option or Result to a
|
|
|
|
|
## new variable. It can be used inside of a conditional expression, for
|
|
|
|
|
## instance in an `if` statement.
|
|
|
|
|
|
2021-05-06 17:12:52 +02:00
|
|
|
name.expectKind({nnkIdent, nnkVarTy})
|
|
|
|
|
if name.kind == nnkIdent:
|
|
|
|
|
quote do: bindLet(`name`, `expression`)
|
|
|
|
|
else:
|
|
|
|
|
let name = name[0]
|
|
|
|
|
quote do: bindVar(`name`, `expression`)
|