Make the Instance class dict compatible to allow for JSON serialization.
I have a specific use case where I want to serialize dissect.cstruct instances to JSON.
This MR introduces two changes to make both Instance and EnumInstance inherit from dict, allowing users of the library to do things like:
my_struct = cstruct()
my_struct.load(definition)
record = my_struct.Record(data)
print(json.dumps(record, cls=CustomEncoder))
Since these instances can contain bytes attributes and that JSON does not support bytes, the specificities of the JSON encoding is left to the user of dissect.cstruct. In the attached example, a UTF-8 decoding with surrogate escape is used but we could also imagine a base64 encoding if the structure holds lots of raw binary data.
A demo example is provided in examples/mirai_json.py
These changes do not introduce API changes nor do they break the test suite. However, I'm open to writing unit tests if you're open to merge this MR :)
Thanks again for this wonderful project !
Just fixed my code with your linter config.
Thanks for the nice idea! Unfortunately there are some issues with subclassing
Instancefromdictas we have plans to merge theInstanceandStructureclasses into a single class. Having that new class be based off ofdictwould be difficult.Would it be feasible to have an
as_dict()function instead? TheEnumInstancecould then be dealt with in aCustomEncoderas I can imagine other users wanting to have just the value of an enum (possibly even just the name) instead of a key/value pair.
I see. We'll probably implement the serialization on our end then, np :)
Since you plan on merging Instance and Structure, I just wanted to mention that outside of JSON serialization, it can also be a bottleneck for users of dissect.cstruct wanting to transfer Instance objects between processes since multiprocessing in Python rely on pickle.
I'll close this once we're sure of the direction to take.
Again, thanks for all your work on this project !
@qkaiser is this still an issue for you with the new dissect cstruct v4?