Created
July 14, 2022 00:16
-
-
Save phase/3205f8af061c691daef4507b5a16f724 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
pub const LoginPacket = struct { | |
id: u32, | |
x: u8, | |
y: u8, | |
z: u8, | |
}; | |
pub const ByteBuf = struct { | |
fn write(_: *ByteBuf, comptime T: type, value: T) void { | |
std.debug.print("write({}, {})\n", .{T, value}); | |
} | |
fn read(_: *ByteBuf, comptime T: type) T { | |
std.debug.print("read({})\n", .{T}); | |
return 5; | |
} | |
}; | |
// comptime function to build a packet serializer by reading the fields of a struct | |
fn packet_serializer(comptime T: type) type { | |
// return an anonymous struct | |
return struct { | |
// write a packet to a bytebuf | |
fn write(byteBuf: *ByteBuf, packet: T) void { | |
// compile-time type reflection | |
switch (@typeInfo(T)) { | |
.Struct => |*strct| { | |
// iterate over every field (at comptime) | |
inline for (strct.fields) |field| { | |
byteBuf.write(field.field_type, @field(packet, field.name)); | |
} | |
}, | |
else => unreachable, // T is not a struct, so we can't serialize it | |
} | |
} | |
// read a packet from a bytebuf | |
fn read(byteBuf: *ByteBuf) T { | |
var packet: T = undefined; | |
// compile-time type reflection | |
switch (@typeInfo(T)) { | |
.Struct => |*strct| { | |
// iterate over every field (at comptime) | |
inline for (strct.fields) |field| { | |
// write the read value to the packet | |
@field(packet, field.name) = byteBuf.read(field.field_type); | |
} | |
}, | |
else => unreachable, // T is not a struct, so we can't serialize it | |
} | |
return packet; | |
} | |
}; | |
} | |
test "packet serializer for LoginPacket" { | |
const LoginPacketSerializer: type = comptime packet_serializer(LoginPacket); | |
const byteBuf = ByteBuf{}; | |
LoginPacketSerializer.write(byteBuf, .{.id = 5, .x = 1, .y = 2, .z = 3}); | |
const packet = LoginPacketSerializer.read(byteBuf); | |
try expect(packet.id == 5); | |
try expect(packet.x == packet.y); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment