Hello guys,
Is there any way to serialize object including its runtime type data? Both marshal and msgpack4nim don't support it out-of-box.
import streams, msgpack4nim
type
TA = object of RootObj
TB = object of TA
f: int
var
a: ref TA
b: ref TB
new(b)
a = b
echo stringify(pack(a))
#produces "[ ]" or "{ }"
#not "[ 0 ]" or '{ "f" : 0 }'
I know about object variants but if I use them I will lose the elegance of dynamic dispatch and will have to write those ugly
case obj.kind
of kndA:
# 50 lines of code
of kndB:
# another 50 loc
# ... etc
One possible solution is to write a macro that will pack class name together with the data, like
genPackers(TA, TB, TC, ...)
# transforms into:
method pack*(a: ref TA): string =
pack "TA" # specify runtime type as string
pack a
method pack*(b: ref TB): string =
pack "TB"
pack b
proc unpack*(data: string): ref TA =
var typ: string = unpack(data)
case typ
of "TA":
result = unpack[TA](data)
of "TB":
result = unpack[TB](data)
# ...
This will probably work, but is there a better solution, without strings of class names and lising all possible classes? Kinda
proc pack(anything: ref TA): string =
pack(anything.runtimeType) # pack internal type info
pack[anything.runtimeType](anything) # pack the object with respect to its runtime type
proc unpack(data: string): ref TA =
let runtimeType = unpack[typeInfo](data) # unpack runtime type
result = unpack[runtimeType](data) # unpack data according to that runtime type
It would be too easy!
import streams, nesm
serializable:
type
TA = object of RootObj
TB = object of TA
f: int
var
a: ref TA
b: ref TB
new(b)
a = b
echo stringify(serialize(a))
lib/nim/system.nim(2833, 7) Error: unhandled exception: kind(thetype[1]) == nnkEmpty
Inheritence not supported in serializable