Tweak fromPreserve for floats and objects

This commit is contained in:
Emery Hemingway 2022-03-08 15:25:03 -06:00
parent 8b52e3baf9
commit 633cb0a3c4
1 changed files with 24 additions and 10 deletions

View File

@ -663,7 +663,7 @@ proc toPreserve*[T](x: T; E = void): Preserve[E] =
for v in x.items: result.sequence.add(toPreserve(v, E)) for v in x.items: result.sequence.add(toPreserve(v, E))
elif T is bool: elif T is bool:
result = Preserve[E](kind: pkBoolean, bool: x) result = Preserve[E](kind: pkBoolean, bool: x)
elif T is float: elif T is float32:
result = Preserve[E](kind: pkFloat, float: x) result = Preserve[E](kind: pkFloat, float: x)
elif T is float64: elif T is float64:
result = Preserve[E](kind: pkDouble, double: x) result = Preserve[E](kind: pkDouble, double: x)
@ -796,10 +796,6 @@ proc fromPreserve*[T, E](v: var T; pr: Preserve[E]): bool =
if pr.kind == pkSignedInteger: if pr.kind == pkSignedInteger:
v = T(pr.int) v = T(pr.int)
result = true result = true
elif T is float:
if pr.kind == pkFloat:
v = pr.float
result = true
elif T is seq[byte]: elif T is seq[byte]:
if pr.kind == pkByteString: if pr.kind == pkByteString:
v = pr.bytes v = pr.bytes
@ -813,6 +809,10 @@ proc fromPreserve*[T, E](v: var T; pr: Preserve[E]): bool =
if not result: if not result:
v.setLen 0 v.setLen 0
break break
elif T is float32:
if pr.kind == pkFloat:
v = pr.float
result = true
elif T is float64: elif T is float64:
case pr.kind case pr.kind
of pkFloat: of pkFloat:
@ -821,6 +821,7 @@ proc fromPreserve*[T, E](v: var T; pr: Preserve[E]): bool =
of pkDouble: of pkDouble:
v = pr.double v = pr.double
result = true result = true
else: discard
elif T is Ordinal | SomeInteger: elif T is Ordinal | SomeInteger:
if pr.kind == pkSignedInteger: if pr.kind == pkSignedInteger:
v = (T)pr.int v = (T)pr.int
@ -855,8 +856,9 @@ proc fromPreserve*[T, E](v: var T; pr: Preserve[E]): bool =
if tupleLen(T) == pr.len: if tupleLen(T) == pr.len:
result = true result = true
for key, val in fieldPairs(v): for key, val in fieldPairs(v):
if result: try: result = fromPreserve(val, pr[toSymbol(key, E)])
result = result and fromPreserve(val, pr[toSymbol(key, E)]) except KeyError: result = false
if not result: break
else: discard else: discard
elif T is ref: elif T is ref:
if isNil(v): new(v) if isNil(v): new(v)
@ -921,9 +923,21 @@ proc fromPreserve*[T, E](v: var T; pr: Preserve[E]): bool =
# hopefully a `discard` of-branch, so discard `pr` # hopefully a `discard` of-branch, so discard `pr`
result = true result = true
if result: break if result: break
else: result = fromPreserveHook(v, pr) else:
else: result = fromPreserveHook(v, pr) if pr.isDictionary:
# the hook doesn't compile but produces a useful error result = true
var i: int
for key, _ in fieldPairs(v):
let val = pr.getOrDefault(toSymbol(key, E))
result = result and fieldFromPreserve(
key, v.dot(key), val)
if not result: break
inc i
result = result and (i == pr.len)
else:
result = fromPreserveHook(v, pr)
# a previous branch determined that the hook does not compile but
# calling it here explicitly produces a reasonable compiler error
if not result: if not result:
trace T, " !- ", pr trace T, " !- ", pr
else: else: