From 93f5c919fb88c58226609aa388862a8f9514f3f1 Mon Sep 17 00:00:00 2001 From: Mark Spanbroek Date: Mon, 31 May 2021 16:24:21 +0200 Subject: [PATCH] Ensure that optional binding works with closures --- questionable/binding.nim | 3 ++- questionable/results.nim | 5 ++++- testmodules/options/test.nim | 14 ++++++++++++++ testmodules/result/test.nim | 14 ++++++++++++++ 4 files changed, 34 insertions(+), 2 deletions(-) diff --git a/questionable/binding.nim b/questionable/binding.nim index 357e683..bc927bd 100644 --- a/questionable/binding.nim +++ b/questionable/binding.nim @@ -6,7 +6,8 @@ proc option[T](option: Option[T]): Option[T] = template bindLet(name, expression): bool = let option = expression.option - template name: auto {.used.} = option.unsafeGet() + const default = typeof(option.unsafeGet()).default + let name = if option.isSome: option.unsafeGet() else: default option.isSome template bindVar(name, expression): bool = diff --git a/questionable/results.nim b/questionable/results.nim index 4dc0de5..763d2e9 100644 --- a/questionable/results.nim +++ b/questionable/results.nim @@ -80,7 +80,10 @@ template `|?`*[T,E](value: Result[T,E], fallback: T): T = proc option*[T,E](value: Result[T,E]): ?T = if value.isOk: - value.unsafeGet.some + try: # workaround for erroneouos exception tracking when T is a closure + value.unsafeGet.some + except Exception as exception: + raise newException(Defect, exception.msg, exception) else: T.none diff --git a/testmodules/options/test.nim b/testmodules/options/test.nim index 6f7683f..3733169 100644 --- a/testmodules/options/test.nim +++ b/testmodules/options/test.nim @@ -148,6 +148,20 @@ suite "optionals": check 42.some.toString == "42" check int.none.toString == "none" + test "=? works with closures": + var called = false + let closure = some(proc () = called = true) + + if a =? none(proc ()): + a() + + check not called + + if a =? closure: + a() + + check called + test "without statement can be used for early returns": proc test1 = without a =? 42.some: diff --git a/testmodules/result/test.nim b/testmodules/result/test.nim index 07b1f97..367baa4 100644 --- a/testmodules/result/test.nim +++ b/testmodules/result/test.nim @@ -151,6 +151,20 @@ suite "result": check 42.success.toString == "42" check int.failure(error).toString == "error" + test "=? works with closures": + var called = false + let closure = success(proc () = called = true) + + if a =? failure(proc (), error): + a() + + check not called + + if a =? closure: + a() + + check called + test "without statement works for results": proc test1 = without a =? 42.success: