diff --git a/questionable/indexing.nim b/questionable/indexing.nim index b794b7a..72e30b7 100644 --- a/questionable/indexing.nim +++ b/questionable/indexing.nim @@ -1,16 +1,23 @@ import std/macros -macro `.?`*(expression: seq | string, brackets: untyped{nkBracket}): untyped = +macro `.?`*(expression: seq | string | openArray, brackets: untyped{nkBracket}): untyped = # chain is of shape: (seq or string).?[index] let index = brackets[0] quote do: block: type T = typeof(`expression`[`index`]) - let evaluated = `expression` - if `index` < evaluated.len: - evaluated[`index`].some + + when typeof(`expression`) is openArray: + if `index` >= `expression`.low and `index` <= `expression`.high: + `expression`[`index`].some + else: + T.none else: - T.none + let evaluated = `expression` + if `index` >= evaluated.low and `index` <= evaluated.high: + evaluated[`index`].some + else: + T.none macro `.?`*(expression: typed, brackets: untyped{nkBracket}): untyped = # chain is of shape: expression.?[index] diff --git a/testmodules/options/test.nim b/testmodules/options/test.nim index 3293e42..26d52ff 100644 --- a/testmodules/options/test.nim +++ b/testmodules/options/test.nim @@ -337,13 +337,23 @@ suite "optionals": test ".?[] can be used for indexing strings without raising IndexDefect": let str = "a" - check str.?[0] == 'a'.some + check str.?[0] == 'a'.some check str.?[1] == char.none + check str.?[-1] == char.none test ".?[] can be used for indexing sequences without raising IndexDefect": let sequence = @[1] check sequence.?[0] == 1.some 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 ".?[] can be followed by calls, operators and indexing": let table = @{"a": @[41, 42]}.toTable