feat: idiomatic zig
This commit is contained in:
@@ -15,48 +15,70 @@ const VERSION: u8 = 1;
|
|||||||
|
|
||||||
const Data = struct {
|
const Data = struct {
|
||||||
message: []const u8,
|
message: []const u8,
|
||||||
|
allocator: ?std.mem.Allocator,
|
||||||
|
|
||||||
|
pub fn init(allocator: ?std.mem.Allocator, message: []const u8) Data {
|
||||||
|
return .{
|
||||||
|
.message = message,
|
||||||
|
.allocator = allocator,
|
||||||
};
|
};
|
||||||
|
|
||||||
const SerializationError = error{ VersionDoesNotMatchError, OutOfMemory, OtherError };
|
|
||||||
|
|
||||||
fn deserialize(allocator: std.mem.Allocator, input: []u8) SerializationError!Data {
|
|
||||||
if (input.len == 0) {
|
|
||||||
return SerializationError.OtherError;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (input[0] != VERSION) {
|
pub fn serialize(self: Data, allocator: std.mem.Allocator) ![]u8 {
|
||||||
return SerializationError.VersionDoesNotMatchError;
|
const messageLen = self.message.len;
|
||||||
}
|
|
||||||
|
|
||||||
const messageLen = input[1];
|
|
||||||
|
|
||||||
const message = try allocator.alloc(u8, messageLen);
|
|
||||||
|
|
||||||
@memcpy(message, input[2..(messageLen + 2)]);
|
|
||||||
|
|
||||||
return .{ .message = message };
|
|
||||||
}
|
|
||||||
fn serialize(allocator: std.mem.Allocator, input: Data) ![]u8 {
|
|
||||||
const messageLen = input.message.len;
|
|
||||||
if (messageLen >= std.math.maxInt(u8)) {
|
if (messageLen >= std.math.maxInt(u8)) {
|
||||||
return SerializationError.OtherError;
|
return error.MessageToLong;
|
||||||
}
|
}
|
||||||
const data = try allocator.alloc(u8, 2 + input.message.len);
|
const data = try allocator.alloc(u8, 2 + self.message.len);
|
||||||
data[0] = VERSION;
|
data[0] = VERSION;
|
||||||
data[1] = @intCast(input.message.len);
|
data[1] = @intCast(self.message.len);
|
||||||
const a = input.message;
|
@memcpy(data[2..], self.message);
|
||||||
@memcpy(data[2..], a);
|
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
test "expect DataV1 can be serialized and deserialized" {
|
pub fn deserialize(allocator: std.mem.Allocator, input: []const u8) !Data {
|
||||||
|
if (input.len < 2) {
|
||||||
|
return error.ProtocolFailure;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (input[0] != VERSION) {
|
||||||
|
return error.VersionMismatch;
|
||||||
|
}
|
||||||
|
|
||||||
|
const messageLen = input[1];
|
||||||
|
const message = try allocator.alloc(u8, messageLen);
|
||||||
|
@memcpy(message, input[2..(messageLen + 2)]);
|
||||||
|
|
||||||
|
return Data.init(allocator, message);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn deinit(self: Data) void {
|
||||||
|
if (self.allocator) |alloc| {
|
||||||
|
alloc.free(self.message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
test "should round trip" {
|
||||||
const message = "Test";
|
const message = "Test";
|
||||||
const expected: Data = .{ .message = message };
|
const expected = Data.init(null, message);
|
||||||
const serialized = try serialize(std.testing.allocator, expected);
|
|
||||||
|
const serialized = try expected.serialize(std.testing.allocator);
|
||||||
defer std.testing.allocator.free(serialized);
|
defer std.testing.allocator.free(serialized);
|
||||||
|
|
||||||
const actual = try deserialize(std.testing.allocator, serialized);
|
const actual = try Data.deserialize(std.testing.allocator, serialized);
|
||||||
defer std.testing.allocator.free(actual.message);
|
defer actual.deinit();
|
||||||
|
|
||||||
try std.testing.expectEqualDeep(expected.message, actual.message);
|
try std.testing.expectEqualDeep(expected.message, actual.message);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
test "should return deserialize error " {
|
||||||
|
try std.testing.expectError(error.ProtocolFailure, Data.deserialize(std.testing.allocator, &.{}));
|
||||||
|
try std.testing.expectError(error.ProtocolFailure, Data.deserialize(std.testing.allocator, &.{VERSION}));
|
||||||
|
try std.testing.expectError(error.VersionMismatch, Data.deserialize(std.testing.allocator, &.{ VERSION + 2, 0 }));
|
||||||
|
}
|
||||||
|
|
||||||
|
test "should deserialize empty message" {
|
||||||
|
const data = try Data.deserialize(std.testing.allocator, &.{ VERSION, 0 });
|
||||||
|
try std.testing.expectEqualStrings("", data.message);
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user