From 92834a8968f2f2e68b49d3191ea6ff056ef4855b Mon Sep 17 00:00:00 2001 From: Emery Hemingway Date: Wed, 7 Dec 2022 03:23:10 -0600 Subject: [PATCH] Add expand, contract for embedded conversions --- src/preserves.nim | 50 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/src/preserves.nim b/src/preserves.nim index 0df0f39..27313d1 100644 --- a/src/preserves.nim +++ b/src/preserves.nim @@ -1213,6 +1213,56 @@ proc mapEmbeds*[A, B](pr: sink Preserve[A]; op: proc (v: A): B): Preserve[B] = of pkEmbedded: result = embed op(pr.embed) +proc contract*[E](pr: sink Preserve[E]; op: proc (v: E): Preserve[void]): Preserve[void] = + ## Convert `Preserve[E]` to `Preserve[void]` using an `E → Preserve[void]` procedure. + if not pr.embedded: + case pr.kind + of pkBoolean, pkFloat, pkDouble, pkSignedInteger, pkString, pkByteString, pkSymbol: + result = cast[Preserve[void]](pr) + of pkRecord: + result = Preserve[void](kind: pr.kind) + result.record = map(pr.record) do (x: Preserve[E]) -> Preserve[void]: + contract(x, op) + of pkSequence: + result = Preserve[void](kind: pr.kind) + result.sequence = map(pr.sequence) do (x: Preserve[E]) -> Preserve[void]: + contract(x, op) + of pkSet: + result = Preserve[void](kind: pr.kind) + result.set = map(pr.set) do (x: Preserve[E]) -> Preserve[void]: + contract(x, op) + of pkDictionary: + result = Preserve[void](kind: pr.kind) + result.dict = map(pr.dict) do (e: DictEntry[E]) -> DictEntry[void]: + (contract(e.key, op), contract(e.val, op)) + of pkEmbedded: + result = embed op(pr.embed) + +proc expand*[E](pr: sink Preserve[void]; op: proc (v: Preserve[void]): Preserve[E]): Preserve[E] = + ## Convert `Preserve[void]` to `Preserve[E]` using an `Preserve[void] → Preserve[E]` procedure. + if not pr.embedded: + case pr.kind + of pkBoolean, pkFloat, pkDouble, pkSignedInteger, pkString, pkByteString, pkSymbol: + result = cast[Preserve[E]](pr) + of pkRecord: + result = Preserve[E](kind: pr.kind) + result.record = map(pr.record) do (x: Preserve[void]) -> Preserve[E]: + expand(x, op) + of pkSequence: + result = Preserve[E](kind: pr.kind) + result.sequence = map(pr.sequence) do (x: Preserve[void]) -> Preserve[E]: + expand(x, op) + of pkSet: + result = Preserve[E](kind: pr.kind) + result.set = map(pr.set) do (x: Preserve[void]) -> Preserve[E]: + expand(x, op) + of pkDictionary: + result = Preserve[E](kind: pr.kind) + result.dict = map(pr.dict) do (e: DictEntry[void]) -> DictEntry[E]: + (expand(e.key, op), expand(e.val, op)) + of pkEmbedded: + result = op(pr.embed) + proc getOrDefault*[T, V](pr: Preserve[T]; key: string; default: V): V = ## Retrieves the value of `pr[key]` if `pr` is a dictionary containing `key` ## or returns the `default` value.