Files
zaprus/src/main.zig

102 lines
3.4 KiB
Zig

const is_debug = builtin.mode == .Debug;
/// This creates a debug allocator that can only be referenced in debug mode.
/// You should check for is_debug around every reference to dba.
var dba: DebugAllocator =
if (is_debug)
DebugAllocator.init
else
@compileError("Should not use debug allocator in release mode");
pub fn main() !void {
defer if (is_debug) {
_ = dba.deinit();
};
const gpa = if (is_debug) dba.allocator() else std.heap.smp_allocator;
// CLI parsing adapted from the example here
// https://github.com/Hejsil/zig-clap/blob/e47028deaefc2fb396d3d9e9f7bd776ae0b2a43a/README.md#examples
// First we specify what parameters our program can take.
// We can use `parseParamsComptime` to parse a string into an array of `Param(Help)`.
const params = comptime clap.parseParamsComptime(
\\-h, --help Display this help and exit.
\\-r, --relay <str> A relay message to send.
\\-d, --dest <str> An IPv4 or <= 4 ASCII byte string.
\\-c, --connect <str> A connection message to send.
\\
);
// Initialize our diagnostics, which can be used for reporting useful errors.
// This is optional. You can also pass `.{}` to `clap.parse` if you don't
// care about the extra information `Diagnostics` provides.
var diag = clap.Diagnostic{};
var res = clap.parse(clap.Help, &params, clap.parsers.default, .{
.diagnostic = &diag,
.allocator = gpa,
}) catch |err| {
// Report useful error and exit.
diag.report(std.io.getStdErr().writer(), err) catch {};
return err;
};
defer res.deinit();
try SaprusClient.init();
defer SaprusClient.deinit();
if (res.args.help != 0) {
return clap.help(std.io.getStdErr().writer(), clap.Help, &params, .{});
}
if (res.args.relay) |r| {
const dest = parseDest(res.args.dest) catch .{ 70, 70, 70, 70 };
try SaprusClient.sendRelay(
if (r.len > 0) r else "Hello darkness my old friend",
dest,
gpa,
);
// std.debug.print("Sent: {s}\n", .{r});
return;
} else if (res.args.connect) |c| {
const conn_res: ?SaprusMessage = SaprusClient.connect(if (c.len > 0) c else "Hello darkness my old friend", gpa) catch |err| switch (err) {
error.WouldBlock => null,
else => return err,
};
defer if (conn_res) |r| r.deinit(gpa);
if (conn_res) |r| {
std.debug.print("{s}\n", .{r.connection.payload});
} else {
std.debug.print("No response from connection request\n", .{});
}
return;
}
return clap.help(std.io.getStdErr().writer(), clap.Help, &params, .{});
}
fn parseDest(in: ?[]const u8) [4]u8 {
if (in) |dest| {
if (dest.len <= 4) {
var res: [4]u8 = @splat(0);
@memcpy(res[0..dest.len], dest);
return res;
}
const addr = std.net.Ip4Address.parse(dest, 0) catch return "FAIL".*;
return @bitCast(addr.sa.addr);
}
return "zap".*;
}
const builtin = @import("builtin");
const std = @import("std");
const DebugAllocator = std.heap.DebugAllocator(.{});
const ArrayList = std.ArrayList;
const zaprus = @import("zaprus");
const SaprusClient = zaprus.Client;
const SaprusMessage = zaprus.Message;
const clap = @import("clap");