mirror of
https://github.com/logos-storage/questionable.git
synced 2026-01-02 13:53:11 +00:00
Evaluate =? expressions only once
This commit is contained in:
parent
4f0010638b
commit
91f97c73ef
@ -23,17 +23,19 @@ template `->?`*[T,U,V](options: (?T, ?U), expression: V): ?V =
|
||||
else:
|
||||
V.none
|
||||
|
||||
template `=?`*[T](name: untyped{nkIdent}, option: ?T): bool =
|
||||
template `=?`*[T](name: untyped{nkIdent}, expression: ?T): bool =
|
||||
let option = expression
|
||||
template name: T {.used.} = option.unsafeGet()
|
||||
option.isSome
|
||||
|
||||
macro `=?`*[T](variable: untyped{nkVarTy}, option: ?T): bool =
|
||||
macro `=?`*[T](variable: untyped{nkVarTy}, expression: ?T): bool =
|
||||
let name = variable[0]
|
||||
quote do:
|
||||
var `name` : typeof(`option`.unsafeGet())
|
||||
if `option`.isSome:
|
||||
`name` = `option`.unsafeGet()
|
||||
`option`.isSome
|
||||
let option = `expression`
|
||||
var `name` : typeof(option.unsafeGet())
|
||||
if option.isSome:
|
||||
`name` = option.unsafeGet()
|
||||
option.isSome
|
||||
|
||||
template `|?`*[T](option: ?T, fallback: T): T =
|
||||
if option.isSome:
|
||||
|
||||
@ -38,17 +38,19 @@ template `->?`*[T,U,V](values: (?!T, ?!U), expression: V): ?!V =
|
||||
template `|?`*[T](value: ?!T, fallback: T): T =
|
||||
value.valueOr(fallback)
|
||||
|
||||
template `=?`*[T](name: untyped{nkIdent}, value: ?!T): bool =
|
||||
template `=?`*[T](name: untyped{nkIdent}, expression: ?!T): bool =
|
||||
let value = expression
|
||||
template name: T {.used.} = value.unsafeGet()
|
||||
value.isOk
|
||||
|
||||
macro `=?`*[T](variable: untyped{nkVarTy}, option: ?!T): bool =
|
||||
macro `=?`*[T](variable: untyped{nkVarTy}, expression: ?!T): bool =
|
||||
let name = variable[0]
|
||||
quote do:
|
||||
var `name` : typeof(`option`.unsafeGet())
|
||||
if `option`.isOk:
|
||||
`name` = `option`.unsafeGet()
|
||||
`option`.isOk
|
||||
let value = `expression`
|
||||
var `name` : typeof(value.unsafeGet())
|
||||
if value.isOk:
|
||||
`name` = value.unsafeGet()
|
||||
value.isOk
|
||||
|
||||
proc option*[T,E](value: Result[T,E]): ?T =
|
||||
if value.isOk:
|
||||
|
||||
@ -87,6 +87,17 @@ suite "optionals":
|
||||
if var a =? int.none:
|
||||
fail
|
||||
|
||||
test "=? evaluates optional expression only once":
|
||||
var count = 0
|
||||
if a =? (inc count; 42.some):
|
||||
let b {.used.} = a
|
||||
check count == 1
|
||||
|
||||
count = 0
|
||||
if var a =? (inc count; 42.some):
|
||||
let b {.used.} = a
|
||||
check count == 1
|
||||
|
||||
test "unary operator `-` works for options":
|
||||
check -(-42.some) == 42.some
|
||||
check -(int.none) == int.none
|
||||
|
||||
@ -91,6 +91,17 @@ suite "result":
|
||||
if var a =? int.failure(error):
|
||||
fail
|
||||
|
||||
test "=? evaluates optional expression only once":
|
||||
var count = 0
|
||||
if a =? (inc count; 42.success):
|
||||
let b {.used.} = a
|
||||
check count == 1
|
||||
|
||||
count = 0
|
||||
if var a =? (inc count; 42.success):
|
||||
let b {.used.} = a
|
||||
check count == 1
|
||||
|
||||
test "catch can be used to convert exceptions to results":
|
||||
check parseInt("42").catch == 42.success
|
||||
check parseInt("foo").catch.error of ValueError
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user