Add preservesEmbedded pragma
This commit is contained in:
parent
d3132391bd
commit
60c5f03637
|
@ -728,6 +728,9 @@ template preservesLiteral*(value: typed) {.pragma.}
|
|||
## Serialize a Preserves literal within this object.
|
||||
## See ``toPreserve``.
|
||||
|
||||
template preservesEmbedded*() {.pragma.}
|
||||
## Pragma to mark a value as embedded by `toPreserve`.
|
||||
|
||||
template unpreservable*() {.pragma.}
|
||||
## Pragma to forbid a type from being converted by ``toPreserve``.
|
||||
## Useful for preventing an embeded type from being encoded
|
||||
|
@ -781,6 +784,9 @@ proc toPreserve*[T](x: T; E = void): Preserve[E] =
|
|||
elif T is distinct:
|
||||
result = toPreserve(x.distinctBase, E)
|
||||
elif T is object:
|
||||
template applyEmbed(key: string; v: var Preserve[E]) {.used.} =
|
||||
when x.dot(key).hasCustomPragma(preservesEmbedded):
|
||||
v.embedded = true
|
||||
template fieldToPreserve(key: string; val: typed): Preserve {.used.} =
|
||||
when x.dot(key).hasCustomPragma(preservesLiteral):
|
||||
const lit = parsePreserves(x.dot(key).getCustomPragmaVal(preservesLiteral))
|
||||
|
@ -798,11 +804,14 @@ proc toPreserve*[T](x: T; E = void): Preserve[E] =
|
|||
else:
|
||||
assert(hasKind and not hasVariant)
|
||||
result = fieldToPreserve(k, v)
|
||||
applyEmbed(k, result)
|
||||
hasVariant = true
|
||||
elif T.hasCustomPragma(preservesRecord):
|
||||
result = Preserve[E](kind: pkRecord)
|
||||
for k, v in x.fieldPairs:
|
||||
result.record.add(fieldToPreserve(k, v))
|
||||
var pr = fieldToPreserve(k, v)
|
||||
applyEmbed(k, pr)
|
||||
result.record.add(pr)
|
||||
result.record.add(tosymbol(T.getCustomPragmaVal(preservesRecord), E))
|
||||
elif T.hasCustomPragma(preservesTuple):
|
||||
result = initSequence[E]()
|
||||
|
@ -812,11 +821,15 @@ proc toPreserve*[T](x: T; E = void): Preserve[E] =
|
|||
result.sequence.add(toPreserve(y, E))
|
||||
# TODO: what if there are fields after the tail?
|
||||
else:
|
||||
result.sequence.add(fieldToPreserve(label, field))
|
||||
var pr = fieldToPreserve(label, field)
|
||||
applyEmbed(label, pr)
|
||||
result.sequence.add(pr)
|
||||
elif T.hasCustomPragma(preservesDictionary):
|
||||
result = initDictionary[E]()
|
||||
for key, val in x.fieldPairs:
|
||||
result[toSymbol(key, E)] = fieldToPreserve(key, val)
|
||||
var pr = fieldToPreserve(key, val)
|
||||
applyEmbed(key, pr)
|
||||
result[toSymbol(key, E)] = pr
|
||||
else: result = toPreserveHook(x, E)
|
||||
else: result = toPreserveHook(x, E)
|
||||
# the hook doesn't compile but produces a useful error
|
||||
|
|
|
@ -10,11 +10,12 @@ suite "conversions":
|
|||
s: string
|
||||
type Foobar {.preservesDictionary.} = object
|
||||
a, b: int
|
||||
c: Bar
|
||||
c {.preservesEmbedded.}: Bar
|
||||
let
|
||||
c = Foobar(a: 1, b: 2, c: ("ku", ))
|
||||
b = toPreserve(c)
|
||||
a = preserveTo(b, Foobar)
|
||||
check($b == """{a: 1 b: 2 c: #!["ku"]}""")
|
||||
check(a.isSome and (get(a) == c))
|
||||
check(b.kind == pkDictionary)
|
||||
|
||||
|
|
Loading…
Reference in New Issue