mirror of
https://github.com/logos-storage/questionable.git
synced 2026-05-23 10:19:26 +00:00
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
|
# 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
|
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`
|
identifiers. This is a limitation of Nim and can be worked around with a `mixin`
|
||||||
statement:
|
statement:
|
||||||
|
|||||||
@ -3,12 +3,14 @@ import std/macros
|
|||||||
import ./chaining
|
import ./chaining
|
||||||
import ./indexing
|
import ./indexing
|
||||||
import ./operators
|
import ./operators
|
||||||
|
import ./without
|
||||||
|
|
||||||
include ./errorban
|
include ./errorban
|
||||||
|
|
||||||
export options
|
export options
|
||||||
export chaining
|
export chaining
|
||||||
export indexing
|
export indexing
|
||||||
|
export without
|
||||||
|
|
||||||
template `?`*(T: typed): type Option[T] =
|
template `?`*(T: typed): type Option[T] =
|
||||||
Option[T]
|
Option[T]
|
||||||
|
|||||||
@ -4,12 +4,14 @@ import ./options
|
|||||||
import ./chaining
|
import ./chaining
|
||||||
import ./indexing
|
import ./indexing
|
||||||
import ./operators
|
import ./operators
|
||||||
|
import ./without
|
||||||
|
|
||||||
include ./errorban
|
include ./errorban
|
||||||
|
|
||||||
export resultsbase except ok, err, isOk, isErr
|
export resultsbase except ok, err, isOk, isErr
|
||||||
export chaining
|
export chaining
|
||||||
export indexing
|
export indexing
|
||||||
|
export without
|
||||||
|
|
||||||
type ResultFailure* = object of CatchableError
|
type ResultFailure* = object of CatchableError
|
||||||
|
|
||||||
|
|||||||
4
questionable/without.nim
Normal file
4
questionable/without.nim
Normal file
@ -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 42.some.toString == "42"
|
||||||
check int.none.toString == "none"
|
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":
|
test ".?[] can be used for indexing tables without raising KeyError":
|
||||||
let table = @{"a": 1, "b": 2}.toTable
|
let table = @{"a": 1, "b": 2}.toTable
|
||||||
check table.?["a"] == 1.some
|
check table.?["a"] == 1.some
|
||||||
@ -194,6 +218,18 @@ suite "optionals":
|
|||||||
else:
|
else:
|
||||||
check not compiles(y)
|
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
|
# Option chaining
|
||||||
|
|
||||||
var numbers: ?seq[int]
|
var numbers: ?seq[int]
|
||||||
|
|||||||
@ -108,6 +108,21 @@ suite "result":
|
|||||||
let b {.used.} = a
|
let b {.used.} = a
|
||||||
check count == 1
|
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":
|
test "catch can be used to convert exceptions to results":
|
||||||
check parseInt("42").catch == 42.success
|
check parseInt("42").catch == 42.success
|
||||||
check parseInt("foo").catch.error of ValueError
|
check parseInt("foo").catch.error of ValueError
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user