From 3ca6381be2de7373a1e5447b6932b89e9aa8f8d8 Mon Sep 17 00:00:00 2001 From: mochalins <117967760+mochalins@users.noreply.github.com> Date: Sat, 21 Sep 2024 02:35:16 +0900 Subject: [PATCH] refactor: Allow backend fns self by val or ref --- src/backend/linux.zig | 77 +++++++++++++++++++++---------------------- src/backend/macos.zig | 15 ++++----- src/serialport.zig | 48 +++++++++++++++++++++++---- 3 files changed, 85 insertions(+), 55 deletions(-) diff --git a/src/backend/linux.zig b/src/backend/linux.zig index a1b007a..0a62055 100644 --- a/src/backend/linux.zig +++ b/src/backend/linux.zig @@ -17,11 +17,11 @@ pub fn open(path: []const u8) !PortImpl { }); } -pub fn close(port: *const PortImpl) void { +pub fn close(port: PortImpl) void { port.close(); } -pub fn configure(port: *const PortImpl, config: serialport.Config) !void { +pub fn configure(port: PortImpl, config: serialport.Config) !void { var settings = try std.posix.tcgetattr(port.handle); settings.iflag = .{}; @@ -55,10 +55,7 @@ pub fn configure(port: *const PortImpl, config: serialport.Config) !void { try std.posix.tcsetattr(port.handle, .NOW, settings); } -pub fn flush( - port: *const PortImpl, - options: serialport.Port.FlushOptions, -) !void { +pub fn flush(port: PortImpl, options: serialport.Port.FlushOptions) !void { if (!options.input and !options.output) return; const TCIFLUSH = 0; @@ -85,7 +82,7 @@ pub fn flush( }; } -pub fn poll(port: *const PortImpl) !bool { +pub fn poll(port: PortImpl) !bool { var pollfds: [1]linux.pollfd = .{ .{ .fd = port.handle, @@ -103,11 +100,11 @@ pub fn poll(port: *const PortImpl) !bool { return true; } -pub fn reader(port: *const PortImpl) Reader { +pub fn reader(port: PortImpl) Reader { return port.reader(); } -pub fn writer(port: *const PortImpl) Writer { +pub fn writer(port: PortImpl) Writer { return port.writer(); } @@ -171,7 +168,7 @@ fn openVirtualPorts(master_port: *PortImpl, slave_port: *PortImpl) !void { }); master_port.* = try open("/dev/ptmx"); - errdefer close(master_port); + errdefer close(master_port.*); if (c.grantpt(master_port.handle) < 0 or c.unlockpt(master_port.handle) < 0) @@ -190,82 +187,82 @@ test { var master: PortImpl = undefined; var slave: PortImpl = undefined; try openVirtualPorts(&master, &slave); - defer close(&master); - defer close(&slave); + defer close(master); + defer close(slave); const config: serialport.Config = .{ .baud_rate = .B230400, .handshake = .software, }; - try configure(&master, config); - try configure(&slave, config); + try configure(master, config); + try configure(slave, config); - const writer_m = writer(&master); - const reader_s = reader(&slave); + const writer_m = writer(master); + const reader_s = reader(slave); - try std.testing.expectEqual(false, try poll(&slave)); + try std.testing.expectEqual(false, try poll(slave)); try std.testing.expectEqual(12, try writer_m.write("test message")); - try std.testing.expectEqual(true, try poll(&slave)); + try std.testing.expectEqual(true, try poll(slave)); var buffer: [16]u8 = undefined; try std.testing.expectEqual(12, try reader_s.read(&buffer)); try std.testing.expectEqualSlices(u8, "test message", buffer[0..12]); - try std.testing.expectEqual(false, try poll(&slave)); + try std.testing.expectEqual(false, try poll(slave)); try std.testing.expectEqual(12, try writer_m.write("test message")); - try std.testing.expectEqual(true, try poll(&slave)); + try std.testing.expectEqual(true, try poll(slave)); var small_buffer: [8]u8 = undefined; try std.testing.expectEqual(8, try reader_s.read(&small_buffer)); try std.testing.expectEqualSlices(u8, "test mes", &small_buffer); - try std.testing.expectEqual(true, try poll(&slave)); + try std.testing.expectEqual(true, try poll(slave)); try std.testing.expectEqual(4, try reader_s.read(&small_buffer)); try std.testing.expectEqualSlices(u8, "sage", small_buffer[0..4]); - try std.testing.expectEqual(false, try poll(&slave)); + try std.testing.expectEqual(false, try poll(slave)); try std.testing.expectEqual(12, try writer_m.write("test message")); - try std.testing.expectEqual(true, try poll(&slave)); - try flush(&slave, .{ .input = true }); - try std.testing.expectEqual(false, try poll(&slave)); + try std.testing.expectEqual(true, try poll(slave)); + try flush(slave, .{ .input = true }); + try std.testing.expectEqual(false, try poll(slave)); } test { var master: PortImpl = undefined; var slave: PortImpl = undefined; try openVirtualPorts(&master, &slave); - defer close(&master); - defer close(&slave); + defer close(master); + defer close(slave); const config: serialport.Config = .{ .baud_rate = .B115200 }; - try configure(&master, config); - try configure(&slave, config); + try configure(master, config); + try configure(slave, config); - const writer_m = writer(&master); - const reader_s = reader(&slave); + const writer_m = writer(master); + const reader_s = reader(slave); - try std.testing.expectEqual(false, try poll(&slave)); + try std.testing.expectEqual(false, try poll(slave)); try std.testing.expectEqual(12, try writer_m.write("test message")); - try std.testing.expectEqual(true, try poll(&slave)); + try std.testing.expectEqual(true, try poll(slave)); var buffer: [16]u8 = undefined; try std.testing.expectEqual(12, try reader_s.read(&buffer)); try std.testing.expectEqualSlices(u8, "test message", buffer[0..12]); - try std.testing.expectEqual(false, try poll(&slave)); + try std.testing.expectEqual(false, try poll(slave)); try std.testing.expectEqual(12, try writer_m.write("test message")); - try std.testing.expectEqual(true, try poll(&slave)); + try std.testing.expectEqual(true, try poll(slave)); var small_buffer: [8]u8 = undefined; try std.testing.expectEqual(8, try reader_s.read(&small_buffer)); try std.testing.expectEqualSlices(u8, "test mes", &small_buffer); - try std.testing.expectEqual(true, try poll(&slave)); + try std.testing.expectEqual(true, try poll(slave)); try std.testing.expectEqual(4, try reader_s.read(&small_buffer)); try std.testing.expectEqualSlices(u8, "sage", small_buffer[0..4]); - try std.testing.expectEqual(false, try poll(&slave)); + try std.testing.expectEqual(false, try poll(slave)); try std.testing.expectEqual(12, try writer_m.write("test message")); - try std.testing.expectEqual(true, try poll(&slave)); - try flush(&slave, .{ .input = true }); - try std.testing.expectEqual(false, try poll(&slave)); + try std.testing.expectEqual(true, try poll(slave)); + try flush(slave, .{ .input = true }); + try std.testing.expectEqual(false, try poll(slave)); } diff --git a/src/backend/macos.zig b/src/backend/macos.zig index 3431fa3..e92f73f 100644 --- a/src/backend/macos.zig +++ b/src/backend/macos.zig @@ -17,11 +17,11 @@ pub fn open(path: []const u8) !PortImpl { }); } -pub fn close(port: *const PortImpl) void { +pub fn close(port: PortImpl) void { port.close(); } -pub fn configure(port: *const PortImpl, config: serialport.Config) !void { +pub fn configure(port: PortImpl, config: serialport.Config) !void { var settings = try std.posix.tcgetattr(port.handle); settings.iflag = .{}; @@ -67,10 +67,7 @@ pub fn configure(port: *const PortImpl, config: serialport.Config) !void { try std.posix.tcsetattr(port.handle, .NOW, settings); } -pub fn flush( - port: *const PortImpl, - options: serialport.Port.FlushOptions, -) !void { +pub fn flush(port: PortImpl, options: serialport.Port.FlushOptions) !void { if (!options.input and !options.output) return; const result = c.tcflush( port.handle, @@ -89,7 +86,7 @@ pub fn flush( }; } -pub fn poll(port: *const PortImpl) !bool { +pub fn poll(port: PortImpl) !bool { var pollfds: [1]std.posix.pollfd = .{ .{ .fd = port.handle, @@ -106,11 +103,11 @@ pub fn poll(port: *const PortImpl) !bool { return true; } -pub fn reader(port: *const PortImpl) Reader { +pub fn reader(port: PortImpl) Reader { return port.reader(); } -pub fn writer(port: *const PortImpl) Writer { +pub fn writer(port: PortImpl) Writer { return port.writer(); } diff --git a/src/serialport.zig b/src/serialport.zig index d61ca0b..52ab30a 100644 --- a/src/serialport.zig +++ b/src/serialport.zig @@ -27,27 +27,63 @@ pub const Port = struct { }; pub fn close(self: *@This()) void { - backend.close(&self._impl); + const fnti = @typeInfo(@TypeOf(backend.close)).@"fn"; + const param_type = @typeInfo(fnti.params[0].type.?); + switch (comptime param_type) { + .pointer => backend.close(&self._impl), + .@"struct" => backend.close(self._impl), + else => @compileError("invalid function signature"), + } } pub fn configure(self: *@This(), config: Config) !void { - return backend.configure(&self._impl, config); + const fnti = @typeInfo(@TypeOf(backend.configure)).@"fn"; + const param_type = @typeInfo(fnti.params[0].type.?); + return switch (comptime param_type) { + .pointer => backend.configure(&self._impl, config), + .@"struct" => backend.configure(self._impl, config), + else => @compileError("invalid function signature"), + }; } pub fn flush(self: *@This(), options: FlushOptions) !void { - return backend.flush(&self._impl, options); + const fnti = @typeInfo(@TypeOf(backend.flush)).@"fn"; + const param_type = @typeInfo(fnti.params[0].type.?); + return switch (comptime param_type) { + .pointer => backend.flush(&self._impl, options), + .@"struct" => backend.flush(self._impl, options), + else => @compileError("invalid function signature"), + }; } pub fn poll(self: *@This()) !bool { - return backend.poll(&self._impl); + const fnti = @typeInfo(@TypeOf(backend.poll)).@"fn"; + const param_type = @typeInfo(fnti.params[0].type.?); + return switch (comptime param_type) { + .pointer => backend.poll(&self._impl), + .@"struct" => backend.poll(self._impl), + else => @compileError("invalid function signature"), + }; } pub fn reader(self: *@This()) Reader { - return backend.reader(&self._impl); + const fnti = @typeInfo(@TypeOf(backend.reader)).@"fn"; + const param_type = @typeInfo(fnti.params[0].type.?); + return switch (comptime param_type) { + .pointer => backend.reader(&self._impl), + .@"struct" => backend.reader(self._impl), + else => @compileError("invalid function signature"), + }; } pub fn writer(self: *@This()) Writer { - return backend.writer(&self._impl); + const fnti = @typeInfo(@TypeOf(backend.writer)).@"fn"; + const param_type = @typeInfo(fnti.params[0].type.?); + return switch (comptime param_type) { + .pointer => backend.writer(&self._impl), + .@"struct" => backend.writer(self._impl), + else => @compileError("invalid function signature"), + }; } };