Page 1 of 1
Using InsertJSONStructure with inherited structures?
Posted: Thu Feb 20, 2025 9:42 pm
by Quin
I have this code:
Code: Select all
EnableExplicit
Structure Packet
Type.i
EndStructure
Structure ConnectionPacket Extends Packet
Who.s
EndStructure
Procedure$ MakePacketJSON(*Packet.Packet)
Protected Res$
If CreateJSON(0)
InsertJSONStructure(JSONValue(0), *Packet, Packet)
Res$ = ComposeJSON(0)
FreeJSON(0)
EndIf
ProcedureReturn Res$
EndProcedure
Define Base.Packet
Base\Type = 1
Debug MakePacketJSON(@Base)
Define Connection.ConnectionPacket
Connection\Type = 2
Connection\Who = "Me"
Debug MakePacketJSON(@Connection)
It works, but the fields that are exclusive to the extended structure type don't get serialized. I want to have a generic function I can just throw and basic Packet type at and get a JSON-formatted version of it, including all its child fields. I'm writing an app that's going to need many different types of packets and this is what came to mind right away, but it doesn't work. Does anyone here have advice on how to make this work, or better ways to accomplish the same goal?
Thanks,
Quin,.
Re: Using InsertJSONStructure with inherited structures?
Posted: Thu Feb 20, 2025 10:54 pm
by Little John
Hi Quin,
I don't think that doing it exactly the way you want is currently possible with PureBasic. Maybe the easiest way is to implement
MakePacketJSON() as Macro rather than as procedure.
Code: Select all
EnableExplicit
Structure Packet
Type.i
EndStructure
Structure ConnectionPacket Extends Packet
Who.s
EndStructure
Macro MakePacketJSON (_buffer_, _structure_)
If CreateJSON(0)
InsertJSONStructure(JSONValue(0), _buffer_, _structure_)
Res$ = ComposeJSON(0)
FreeJSON(0)
EndIf
EndMacro
Define Base.Packet, Connection.ConnectionPacket, Res$
Base\Type = 1
MakePacketJSON(@Base, Packet)
Debug Res$
Connection\Type = 2
Connection\Who = "Me"
MakePacketJSON(@Connection, ConnectionPacket)
Debug Res$
Re: Using InsertJSONStructure with inherited structures?
Posted: Thu Feb 20, 2025 10:57 pm
by Quin
LittleJohn,
This is perfect! Thank you! I've used macros for tons of stuff like this before, no idea why it didn't come to me here.
Re: Using InsertJSONStructure with inherited structures?
Posted: Thu Feb 20, 2025 10:59 pm
by Little John
I know that effect very well: Sometimes I cannot see the wood for the trees.

Re: Using InsertJSONStructure with inherited structures?
Posted: Thu Feb 20, 2025 11:32 pm
by Little John
I just had another idea: Pass a
generic pointer and an additional 'type' parameter to the procedure
MakePacketJSON(). Unfortunately, we can't pass a structure name as parameter to a procedure.
Code: Select all
EnableExplicit
Structure Packet
Type.i
EndStructure
Structure ConnectionPacket Extends Packet
Who.s
EndStructure
Procedure$ MakePacketJSON (*p, type.i)
Protected Res$
If CreateJSON(0)
Select type
Case 1
InsertJSONStructure(JSONValue(0), *p, Packet)
Case 2
InsertJSONStructure(JSONValue(0), *p, ConnectionPacket)
Default
; Error
EndSelect
Res$ = ComposeJSON(0)
FreeJSON(0)
EndIf
ProcedureReturn Res$
EndProcedure
Define Base.Packet
Base\Type = 1
Debug MakePacketJSON(@Base, 1)
Define Connection.ConnectionPacket
Connection\Type = 2
Connection\Who = "Me"
Debug MakePacketJSON(@Connection, 2)
Re: Using InsertJSONStructure with inherited structures?
Posted: Thu Feb 20, 2025 11:57 pm
by Quin
Very nice! I think I still prefer the macro, but this is a neat approach as well.
I wish we could pass a structure name to a procedure like you can to AllocateStructure, InsertJSONStructure etc. from actual PB code. If we could I would just make the function take a structure name as the second parameter instead of a type, so no select is needed. Maybe something for the wishlist.
Re: Using InsertJSONStructure with inherited structures?
Posted: Fri Feb 21, 2025 1:30 am
by idle
This is a case where jsonRuntimeStructure support would be useful, it's what I'm using for my db engine so it can get and set arbitrary user structures via runtime reflection using a string of the type rather than the compile time structure.
so rather than using a bunch of selects on users types to marshal the structures it can be done at runtime.
https://www.purebasic.fr/english/viewto ... 49#p628049