Add `step` func as a no-effects substitue for `[]` proc

ehmry/xdg_open_ng#2
This commit is contained in:
Emery Hemingway 2022-03-18 09:44:20 -05:00
parent a6b31247cf
commit 5408cb859a
2 changed files with 23 additions and 3 deletions

View File

@ -1,6 +1,6 @@
# Package
version = "3.2.0" # versioned in git, this version is just to confuse nimble
version = "3.3.0" # versioned in git, this version is just to confuse nimble
author = "Emery Hemingway"
description = "data model and serialization format"
license = "Unlicense"

View File

@ -9,7 +9,7 @@ from std/strutils import parseEnum
import ./preserves/private/dot
when defined(tracePreserves):
template trace(args: varargs[untyped]) = stderr.writeLine(args)
template trace(args: varargs[untyped]) = {.cast(noSideEffect).}: stderr.writeLine(args)
else:
template trace(args: varargs[untyped]) = discard
@ -241,7 +241,8 @@ proc excl*(pr: var Preserve; key: Preserve) =
break
proc `[]`*(pr, key: Preserve): Preserve =
## Select a value by `key` from the Preserves dictionary `pr`.
## Select a value by `key` from `pr`.
## Works for sequences, records, and dictionaries.
if pr.isDictionary:
for (k, v) in pr.dict.items:
if k == key: return v
@ -251,6 +252,25 @@ proc `[]`*(pr, key: Preserve): Preserve =
else:
raise newException(ValueError, "invalid Preserves indexing")
func step*(pr, idx: Preserve): Option[Preserve] =
## Step into `pr` by index `idx`.
## Works for sequences, records, and dictionaries.
runnableExamples:
import options
import preserves, preserves/parse
assert step(parsePreserves("""<foo 1 2>"""), 1.toPreserve) == some(2.toPreserve)
assert step(parsePreserves("""{ foo: 1 bar: 2}"""), "foo".toSymbol) == some(1.toPreserve)
assert step(parsePreserves("""[ ]"""), 1.toPreserve) == none(Preserve[void])
if pr.isDictionary:
for (k, v) in pr.dict.items:
if k == idx:
result = some(v)
break
elif (pr.isRecord or pr.isSequence) and idx.isInteger:
let i = int idx.int
if i < pr.len:
result = some(pr[i])
proc `[]=`*(pr: var Preserve; key, val: Preserve) =
## Insert `val` by `key` in the Preserves dictionary `pr`.
for i in 0..pr.dict.high: