Using InsertJSONStructure with inherited structures?

Just starting out? Need help? Post your questions and find answers here.
Quin
Addict
Addict
Posts: 1135
Joined: Thu Mar 31, 2022 7:03 pm
Location: Colorado, United States
Contact:

Using InsertJSONStructure with inherited structures?

Post 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,.
Little John
Addict
Addict
Posts: 4802
Joined: Thu Jun 07, 2007 3:25 pm
Location: Berlin, Germany

Re: Using InsertJSONStructure with inherited structures?

Post 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$
Quin
Addict
Addict
Posts: 1135
Joined: Thu Mar 31, 2022 7:03 pm
Location: Colorado, United States
Contact:

Re: Using InsertJSONStructure with inherited structures?

Post 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.
Little John
Addict
Addict
Posts: 4802
Joined: Thu Jun 07, 2007 3:25 pm
Location: Berlin, Germany

Re: Using InsertJSONStructure with inherited structures?

Post by Little John »

I know that effect very well: Sometimes I cannot see the wood for the trees. ;-)
Little John
Addict
Addict
Posts: 4802
Joined: Thu Jun 07, 2007 3:25 pm
Location: Berlin, Germany

Re: Using InsertJSONStructure with inherited structures?

Post 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)
Quin
Addict
Addict
Posts: 1135
Joined: Thu Mar 31, 2022 7:03 pm
Location: Colorado, United States
Contact:

Re: Using InsertJSONStructure with inherited structures?

Post 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.
User avatar
idle
Always Here
Always Here
Posts: 6026
Joined: Fri Sep 21, 2007 5:52 am
Location: New Zealand

Re: Using InsertJSONStructure with inherited structures?

Post 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
Post Reply