Hello guys,

Is there any way to serialize object including its runtime type data? Both 
[marshal](https://nim-lang.org/docs/marshal.html) and 
[msgpack4nim](https://github.com/jangko/msgpack4nim#ref-types) 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
    

Reply via email to