mirror of
https://github.com/logos-storage/questionable.git
synced 2026-01-02 13:53:11 +00:00
Support for .?[] operator on openArrays (#52)
* Support for .?[] operator on openArrays * Operator .?[] evaluates openArray expression only once * Fix for Nim 1.2.x --------- Co-authored-by: Mark Spanbroek <mark@spanbroek.net>
This commit is contained in:
parent
2dd6b6b220
commit
1f0afff48b
@ -1,16 +1,24 @@
|
|||||||
import std/macros
|
import std/macros
|
||||||
|
import std/options
|
||||||
|
|
||||||
macro `.?`*(expression: seq | string, brackets: untyped{nkBracket}): untyped =
|
proc safeGet[T](expression: seq[T] | openArray[T], index: int): Option[T] =
|
||||||
# chain is of shape: (seq or string).?[index]
|
if index >= expression.low and index <= expression.high:
|
||||||
let index = brackets[0]
|
expression[index].some
|
||||||
quote do:
|
else:
|
||||||
block:
|
T.none
|
||||||
type T = typeof(`expression`[`index`])
|
|
||||||
let evaluated = `expression`
|
proc safeGet(expression: string, index: int): Option[char] =
|
||||||
if `index` < evaluated.len:
|
if index >= expression.low and index <= expression.high:
|
||||||
evaluated[`index`].some
|
expression[index].some
|
||||||
else:
|
else:
|
||||||
T.none
|
char.none
|
||||||
|
|
||||||
|
macro `.?`*(expression: seq | string | openArray, brackets: untyped{nkBracket}): untyped =
|
||||||
|
# chain is of shape: (seq or string or openArray).?[index]
|
||||||
|
let index = brackets[0]
|
||||||
|
quote do:
|
||||||
|
block:
|
||||||
|
safeGet(`expression`, `index`)
|
||||||
|
|
||||||
macro `.?`*(expression: typed, brackets: untyped{nkBracket}): untyped =
|
macro `.?`*(expression: typed, brackets: untyped{nkBracket}): untyped =
|
||||||
# chain is of shape: expression.?[index]
|
# chain is of shape: expression.?[index]
|
||||||
|
|||||||
@ -337,13 +337,28 @@ suite "optionals":
|
|||||||
|
|
||||||
test ".?[] can be used for indexing strings without raising IndexDefect":
|
test ".?[] can be used for indexing strings without raising IndexDefect":
|
||||||
let str = "a"
|
let str = "a"
|
||||||
check str.?[0] == 'a'.some
|
check str.?[0] == 'a'.some
|
||||||
check str.?[1] == char.none
|
check str.?[1] == char.none
|
||||||
|
check str.?[-1] == char.none
|
||||||
|
|
||||||
test ".?[] can be used for indexing sequences without raising IndexDefect":
|
test ".?[] can be used for indexing sequences without raising IndexDefect":
|
||||||
let sequence = @[1]
|
let sequence = @[1]
|
||||||
check sequence.?[0] == 1.some
|
check sequence.?[0] == 1.some
|
||||||
check sequence.?[1] == int.none
|
check sequence.?[1] == int.none
|
||||||
|
check sequence.?[-1] == int.none
|
||||||
|
|
||||||
|
test ".?[] can be used for indexing openArrays without raising IndexDefect":
|
||||||
|
proc checkOpenArray(oa: openArray[int]): void =
|
||||||
|
check oa.?[0] == 1.some
|
||||||
|
check oa.?[1] == int.none
|
||||||
|
check oa.?[-1] == int.none
|
||||||
|
|
||||||
|
checkOpenArray(@[1])
|
||||||
|
|
||||||
|
test ".?[] evaluates openArray expression only once":
|
||||||
|
var count = 0
|
||||||
|
discard (inc count; @[1].toOpenArray(0, 0)).?[0]
|
||||||
|
check count == 1
|
||||||
|
|
||||||
test ".?[] can be followed by calls, operators and indexing":
|
test ".?[] can be followed by calls, operators and indexing":
|
||||||
let table = @{"a": @[41, 42]}.toTable
|
let table = @{"a": @[41, 42]}.toTable
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user