diff --git a/preserves.nimble b/preserves.nimble index f86ad74..0377d28 100644 --- a/preserves.nimble +++ b/preserves.nimble @@ -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" diff --git a/src/preserves.nim b/src/preserves.nim index db65feb..1648410 100644 --- a/src/preserves.nim +++ b/src/preserves.nim @@ -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(""""""), 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: