IMHO there’s still too many transport layer details in the readme (like “designed for peer-to-peer” - this should be irrelevant for a message protocol), currrently it’s a bit unclear if this is heading for something like protobuf, ZeroMQ, a “better” HTTP or RakNet/ENET.
All those have wildly different use cases and have very different designs for good reason (Protobuf is purely a protocol codec, and doesn’t care about the transport layer, ZeroMQ is nice for communicating between services, HTTP is nice for client/server communication, and RakNet/ENET are good for games but only care about the transport layer but not the message protocol format).
I would go for a pure protobuf replacement (e.g. just the message encoder/decoder), and ideally attempt to use Zig’s comptime reflection features to derive the message format directly from structs - or maybe alternatively go the other way around, describe the message format in a .zon file which is imported and comptime code builds the message structs and message validation functions from the imported zon (not sure if the latter is possible though).
The other way around (use Zig structs as the source of truth and derive the message format from those) may be tricky because Zig lacks custom attributes which would be needed to attach metadata to structs and struct items.
E.g. this would be a nice research project, but current Zig may lack features (it would be a nice design goal for the Zig language to enable such use cases without having to fall back to code generation).
It doesn’t need them, we can reify type information at comptime in a format usable in runtime code. That’s basically how format functions work, if you squint.
To quote the IETF: I believe in rough consensus and running code. Show me some code.
…etc… the data inside @meta() would be .zon-style free form and attached to the type where it is accessible via comptime code (which then would need to be able to build a runtime function which describes the UI though).
…as I said, the other way around (use a .zon as source of truth and build types and functions from that) might make more sense.
…somehow I always end up at “Zig should be able to build functions with comptime code instead of just types”
PS: building a UI with the description as comptime input param might work with the current features though…
PPS: I switched from ‘message protocol’ to ‘ui meta data’ because IMHO that’s a more common use case
The idea is to create a pub decl that contains meta options for the fields of the parent type. In the link above I define which fields should be skipped when serializing / deserializing (Ziggy is a data serialization format), but you could put there arbitrary options, like field name mapping, etc.
With this method you can do everything that hypothetical field attributes could do and this way you also force namespacing of these meta attributes, which is something that field attributes in, say, Go, usually don’t do, occasionally driving you into a corner.
I see, clever! And yeah, looks like this is actually more flexible than ‘meta-attributes’ - and you can have separate ‘attribute blocks’ for different ‘processors’. I need to chew on that idea for a bit