summaryrefslogtreecommitdiff
path: root/src/server/main.zig
diff options
context:
space:
mode:
authorRobby Zambito <contact@robbyzambito.me>2026-01-02 15:19:19 +0000
committerRobby Zambito <contact@robbyzambito.me>2026-01-02 15:29:58 +0000
commit2be370e379959e2763e70851cf14ecfca07754fc (patch)
tree54412e021efef581490ebc985ca5b161f1faeee0 /src/server/main.zig
parent539255adb1f0a681ff49ebfb9e1e3c7198ad5310 (diff)
Support subject patterns
clean up some tests
Diffstat (limited to 'src/server/main.zig')
-rw-r--r--src/server/main.zig37
1 files changed, 33 insertions, 4 deletions
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 {