`without` statement
This commit is contained in:
parent
827214f7a9
commit
ef5f796463
12
Readme.md
12
Readme.md
|
@ -63,6 +63,18 @@ else:
|
|||
# this is reached, and y is not defined
|
||||
```
|
||||
|
||||
The `without` statement can be used to place guards that ensure that an optional
|
||||
contains a value:
|
||||
|
||||
```nim
|
||||
proc someProc(option: ?int) =
|
||||
without value =? option:
|
||||
# option did not contain a value
|
||||
return
|
||||
|
||||
# use value
|
||||
```
|
||||
|
||||
When using `=?` in generic code you may face errors about undeclared
|
||||
identifiers. This is a limitation of Nim and can be worked around with a `mixin`
|
||||
statement:
|
||||
|
|
|
@ -3,12 +3,14 @@ import std/macros
|
|||
import ./chaining
|
||||
import ./indexing
|
||||
import ./operators
|
||||
import ./without
|
||||
|
||||
include ./errorban
|
||||
|
||||
export options
|
||||
export chaining
|
||||
export indexing
|
||||
export without
|
||||
|
||||
template `?`*(T: typed): type Option[T] =
|
||||
Option[T]
|
||||
|
|
|
@ -4,12 +4,14 @@ import ./options
|
|||
import ./chaining
|
||||
import ./indexing
|
||||
import ./operators
|
||||
import ./without
|
||||
|
||||
include ./errorban
|
||||
|
||||
export resultsbase except ok, err, isOk, isErr
|
||||
export chaining
|
||||
export indexing
|
||||
export without
|
||||
|
||||
type ResultFailure* = object of CatchableError
|
||||
|
||||
|
|
|
@ -0,0 +1,4 @@
|
|||
template without*(expression, body) =
|
||||
let ok = expression
|
||||
if not ok:
|
||||
body
|
|
@ -116,6 +116,30 @@ suite "optionals":
|
|||
check 42.some.toString == "42"
|
||||
check int.none.toString == "none"
|
||||
|
||||
test "without statement can be used for early returns":
|
||||
proc test1 =
|
||||
without a =? 42.some:
|
||||
fail
|
||||
return
|
||||
check a == 42
|
||||
|
||||
proc test2 =
|
||||
without a =? int.none:
|
||||
return
|
||||
fail
|
||||
|
||||
test1()
|
||||
test2()
|
||||
|
||||
test "without statement evaluates optional expression only once":
|
||||
proc test =
|
||||
var count = 0
|
||||
without a =? (inc count; 42.some):
|
||||
discard
|
||||
check count == 1
|
||||
|
||||
test()
|
||||
|
||||
test ".?[] can be used for indexing tables without raising KeyError":
|
||||
let table = @{"a": 1, "b": 2}.toTable
|
||||
check table.?["a"] == 1.some
|
||||
|
@ -194,6 +218,18 @@ suite "optionals":
|
|||
else:
|
||||
check not compiles(y)
|
||||
|
||||
# without statement
|
||||
|
||||
proc someProc(option: ?int) =
|
||||
without value =? option:
|
||||
check option.isNone
|
||||
return
|
||||
|
||||
check value == 42
|
||||
|
||||
someProc(int.none)
|
||||
someProc(42.some)
|
||||
|
||||
# Option chaining
|
||||
|
||||
var numbers: ?seq[int]
|
||||
|
|
|
@ -108,6 +108,21 @@ suite "result":
|
|||
let b {.used.} = a
|
||||
check count == 1
|
||||
|
||||
test "without statement works for results":
|
||||
proc test1 =
|
||||
without a =? 42.success:
|
||||
fail
|
||||
return
|
||||
check a == 42
|
||||
|
||||
proc test2 =
|
||||
without a =? int.failure "error":
|
||||
return
|
||||
fail
|
||||
|
||||
test1()
|
||||
test2()
|
||||
|
||||
test "catch can be used to convert exceptions to results":
|
||||
check parseInt("42").catch == 42.success
|
||||
check parseInt("foo").catch.error of ValueError
|
||||
|
|
Loading…
Reference in New Issue