From 2be370e379959e2763e70851cf14ecfca07754fc Mon Sep 17 00:00:00 2001 From: Robby Zambito Date: Fri, 2 Jan 2026 15:19:19 +0000 Subject: Support subject patterns clean up some tests --- src/server/main.zig | 37 +++++++++++++++++++++++++++++++++---- 1 file changed, 33 insertions(+), 4 deletions(-) (limited to 'src/server/main.zig') diff --git a/src/server/main.zig b/src/server/main.zig index 59dfa94..81c8fbd 100644 --- a/src/server/main.zig +++ b/src/server/main.zig @@ -83,7 +83,7 @@ pub fn start(server: *Server, io: std.Io, gpa: std.mem.Allocator) !void { server.info.port, ), io, .{ .reuse_address = true }); defer tcp_server.deinit(io); - std.log.info("Server listening on {s}:{d}", .{server.info.host, server.info.port}); + std.log.info("Server listening on {s}:{d}", .{ server.info.host, server.info.port }); var client_group: std.Io.Group = .init; defer client_group.cancel(io); @@ -147,12 +147,12 @@ fn handleConnection( //const allocator = if (builtin.mode == .Debug or builtin.mode == .ReleaseSafe) client_allocator.allocator() else server_allocator; // Set up client writer - var w_buffer: [1024*16]u8 = undefined; + var w_buffer: [1024 * 16]u8 = undefined; var writer = stream.writer(io, &w_buffer); const out = &writer.interface; // Set up client reader - var r_buffer: [1024*16]u8 = undefined; + var r_buffer: [1024 * 16]u8 = undefined; var reader = stream.reader(io, &r_buffer); const in = &reader.interface; @@ -216,7 +216,36 @@ fn handleConnection( } fn subjectMatches(sub_subject: []const u8, pub_subject: []const u8) bool { - return std.mem.eql(u8, sub_subject, pub_subject); + // TODO: assert that sub_subject and pub_subject are valid. + var sub_iter = std.mem.splitScalar(u8, sub_subject, '.'); + var pub_iter = std.mem.splitScalar(u8, pub_subject, '.'); + + while (sub_iter.next()) |st| { + const pt = pub_iter.next() orelse return false; + + if (std.mem.eql(u8, st, ">")) return true; + + if (!std.mem.eql(u8, st, "*") and !std.mem.eql(u8, st, pt)) { + return false; + } + } + + return pub_iter.next() == null; +} + +test subjectMatches { + try std.testing.expect(subjectMatches("foo", "foo")); + try std.testing.expect(!subjectMatches("foo", "bar")); + + try std.testing.expect(subjectMatches("foo.*", "foo.bar")); + try std.testing.expect(!subjectMatches("foo.*", "foo")); + try std.testing.expect(!subjectMatches("foo.>", "foo")); + + // the wildcard subscriptions foo.*.quux and foo.> both match foo.bar.quux, but only the latter matches foo.bar.baz. + try std.testing.expect(subjectMatches("foo.*.quux", "foo.bar.quux")); + try std.testing.expect(subjectMatches("foo.>", "foo.bar.quux")); + try std.testing.expect(!subjectMatches("foo.*.quux", "foo.bar.baz")); + try std.testing.expect(subjectMatches("foo.>", "foo.bar.baz")); } fn publishMessage(server: *Server, io: std.Io, alloc: std.mem.Allocator, source_client: *Client, msg: Message.Pub) !void { -- cgit