const std = @import("std"); const builtin = @import("builtin"); const zits = @import("zits"); const yazap = @import("yazap"); const Message = zits.MessageParser.Message; const Server = zits.Server; const serve = @import("./subcommand/serve.zig").main; pub fn main() !void { var dba: std.heap.DebugAllocator(.{}) = .init; defer _ = dba.deinit(); const gpa = if (builtin.mode == .Debug or builtin.mode == .ReleaseSafe) dba.allocator() else std.heap.smp_allocator; 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.message.Message.ServerInfo, .host).defaultValue().?}, ), ), yazap.Arg.singleValueOption( "port", 'p', std.fmt.comptimePrint( "Port to listen on (default: {d})", .{std.meta.fieldInfo(zits.Server.message.Message.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); var io_impl: std.Io.Threaded = .init_single_threaded; defer io_impl.deinit(); const io = io_impl.io(); const matches = try app.parseProcess(io); if (matches.subcommandMatches("serve")) |serve_matches| { var info: zits.Server.message.Message.ServerInfo = .{ .server_id = zits.Server.default_id, .server_name = zits.Server.default_name, .version = "zits-master", .max_payload = 1048576, .headers = true, }; 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 serve(gpa, info); return; } else if (matches.subcommandMatches("pub")) |_| { std.debug.print("Unimplemented\n", .{}); return; } try app.displayHelp(io); } pub const std_options: std.Options = .{ // By default, in safe build modes, the standard library will attach a segfault handler to the program to // print a helpful stack trace if a segmentation fault occurs. Here, we can disable this, or even enable // it in unsafe build modes. .enable_segfault_handler = true, // This is the logging function used by `std.log`. .logFn = myLogFn, }; fn myLogFn( comptime level: std.log.Level, comptime scope: @EnumLiteral(), comptime format: []const u8, args: anytype, ) void { if (scope == .zits) { std.log.defaultLog(level, std.log.default_log_scope, format, args); } else { std.log.defaultLog(level, scope, format, args); } }