From 41f4ee721b138304294b185185dc6fc51549c5b9 Mon Sep 17 00:00:00 2001 From: Robby Zambito Date: Sat, 29 Nov 2025 21:20:56 -0500 Subject: Switch from clap to yazap This is compatible with the latest 0.16.0 nightly build. It is also a bit less magic than clap. --- build.zig | 4 +- build.zig.zon | 6 +-- src/main.zig | 107 ++++++++++++++++++++++++++-------------------------- src/server/main.zig | 15 ++++++-- 4 files changed, 70 insertions(+), 62 deletions(-) diff --git a/build.zig b/build.zig index 4c1fabd..4a90d7b 100644 --- a/build.zig +++ b/build.zig @@ -83,8 +83,8 @@ pub fn build(b: *std.Build) void { }), }); - const clap = b.dependency("clap", .{}); - exe.root_module.addImport("clap", clap.module("clap")); + const yazap = b.dependency("yazap", .{}); + exe.root_module.addImport("yazap", yazap.module("yazap")); // This declares intent for the executable to be installed into the // install prefix when running `zig build` (i.e. when executing the default diff --git a/build.zig.zon b/build.zig.zon index b62bab4..2c23678 100644 --- a/build.zig.zon +++ b/build.zig.zon @@ -32,9 +32,9 @@ // Once all dependencies are fetched, `zig build` no longer requires // internet connectivity. .dependencies = .{ - .clap = .{ - .url = "git+https://github.com/Hejsil/zig-clap#b7e3348ed60f99ba32c75aa707ff7c87adc31b36", - .hash = "clap-0.11.0-oBajB-TnAQC7yPLnZRT5WzHZ_4Ly4dX2OILskli74b9H", + .yazap = .{ + .url = "git+https://github.com/prajwalch/yazap#a920616e3a6676362735a2f5ae195ec320f058fb", + .hash = "yazap-0.6.3-Z1t-Emb0AQD_SkYf4dz_nEmAh9oRKiu6nexSJMGK3wcf", }, }, .paths = .{ diff --git a/src/main.zig b/src/main.zig index ea188fb..367cb62 100644 --- a/src/main.zig +++ b/src/main.zig @@ -1,67 +1,68 @@ const std = @import("std"); const zits = @import("zits"); -const clap = @import("clap"); +const yazap = @import("yazap"); const Message = zits.MessageParser.Message; const Server = zits.Server; -const SubCommands = enum { - help, - serve, - @"pub", -}; - -const main_parsers = .{ - .command = clap.parsers.enumeration(SubCommands), -}; - -// The parameters for `main`. Parameters for the subcommands are specified further down. -const main_params = clap.parseParamsComptime( - \\-h, --help Display this help and exit. - \\ - \\ -); - -// To pass around arguments returned by clap, `clap.Result` and `clap.ResultEx` can be used to -// get the return type of `clap.parse` and `clap.parseEx`. -pub const MainArgs = clap.ResultEx(clap.Help, &main_params, main_parsers); - pub fn main() !void { var dba: std.heap.DebugAllocator(.{}) = .init; defer _ = dba.deinit(); const gpa = dba.allocator(); - var iter = try std.process.ArgIterator.initWithAllocator(gpa); - defer iter.deinit(); - - _ = iter.next(); - - var diag = clap.Diagnostic{}; - var res = clap.parseEx(clap.Help, &main_params, main_parsers, &iter, .{ - .diagnostic = &diag, - .allocator = gpa, - - // Terminate the parsing of arguments after parsing the first positional (0 is passed - // here because parsed positionals are, like slices and arrays, indexed starting at 0). - // - // This will terminate the parsing after parsing the subcommand enum and leave `iter` - // not fully consumed. It can then be reused to parse the arguments for subcommands. - .terminating_positional = 0, - }) catch |err| { - try diag.reportToFile(.stderr(), err); - return err; - }; - defer res.deinit(); - std.debug.print("res: {any}\n", .{res}); - - if (res.args.help != 0) - return clap.helpToFile(.stderr(), clap.Help, &main_params, .{}); - - const command = res.positionals[0] orelse return error.MissingCommand; - switch (command) { - .help => return clap.helpToFile(.stderr(), clap.Help, &main_params, .{}), - .serve => try Server.main(gpa, &iter, res), - .@"pub" => unreachable, + var app = yazap.App.init(gpa, "zits", "High performance NATS compatible client and server."); + defer app.deinit(); + + var zits_app = app.rootCommand(); + + var server_cmd = app.createCommand("serve", "Run a high performance NATS compatible server."); + try server_cmd.addArgs(&[_]yazap.Arg{ + yazap.Arg.singleValueOption( + "addr", + 'a', + std.fmt.comptimePrint( + "Address to bind to (default: {s})", + .{std.meta.fieldInfo(zits.Server.ServerInfo, .host).defaultValue().?}, + ), + ), + yazap.Arg.singleValueOption( + "port", + 'p', + std.fmt.comptimePrint( + "Port to listen on (default: {d})", + .{std.meta.fieldInfo(zits.Server.ServerInfo, .port).defaultValue().?}, + ), + ), + yazap.Arg.singleValueOption( + "name", + 'n', + "Server name (default: auto)", + ), + }); + try zits_app.addSubcommand(server_cmd); + + const pub_cmd = app.createCommand("pub", "Publish a message."); + try zits_app.addSubcommand(pub_cmd); + + const matches = try app.parseProcess(); + + if (matches.subcommandMatches("serve")) |serve_matches| { + var info: zits.Server.ServerInfo = .{ + .server_id = zits.Server.createId(), + .server_name = zits.Server.createName(), + .version = "zits-master", + .max_payload = 99999, + }; + if (serve_matches.getSingleValue("port")) |port| { + info.port = std.fmt.parseUnsigned(@TypeOf(info.port), port, 10) catch |err| std.process.fatal("Could not parse port ({s}): {}\n", .{ port, err }); + } + + if (serve_matches.getSingleValue("name")) |name| { + info.server_name = name; + } + + try Server.main(gpa, info); + return; } } diff --git a/src/server/main.zig b/src/server/main.zig index e0058a7..b26f4b0 100644 --- a/src/server/main.zig +++ b/src/server/main.zig @@ -3,7 +3,7 @@ const Message = @import("./message_parser.zig"); const ClientState = @import("./client.zig"); -const ServerInfo = struct { +pub const ServerInfo = struct { /// The unique identifier of the NATS server. server_id: []const u8, /// The name of the NATS server. @@ -18,7 +18,7 @@ const ServerInfo = struct { host: []const u8 = "0.0.0.0", /// The port number the NATS server is configured /// to listen on. - port: u16 = 6868, + port: u16 = 4222, /// Whether the server supports headers. headers: bool = false, /// Maximum payload size, in bytes, that the server @@ -36,9 +36,8 @@ clients: std.AutoHashMapUnmanaged(u64, ClientState) = .empty, /// Map of subjects to client IDs that are subscribed to that subject. subscriptions: std.StringHashMapUnmanaged(std.ArrayList(u64)), -pub fn main(gpa: std.mem.Allocator, iter: *std.process.ArgIterator, main_args: anytype) !void { +pub fn main(gpa: std.mem.Allocator, main_args: anytype) !void { _ = gpa; - _ = iter; _ = main_args; } @@ -107,3 +106,11 @@ fn writeInfo(out: *std.Io.Writer, info: ServerInfo) !void { _ = try out.write("\r\n"); try out.flush(); } + +pub fn createId() []const u8 { + return "SERVERID"; +} + +pub fn createName() []const u8 { + return "SERVERNAME"; +} -- cgit