summaryrefslogtreecommitdiff
path: root/clap.zig
diff options
context:
space:
mode:
authorGravatar Jimmi Holst Christensen2020-11-03 20:04:52 +0100
committerGravatar Jimmi Holst Christensen2020-11-03 20:15:00 +0100
commit7f82f87c310a5db3933551fd0df3d0548abf9f7c (patch)
tree28b7385f4f50934a98df4e032b40aedfcc76ae01 /clap.zig
parentReplace `var` with `anytype` (diff)
downloadzig-clap-7f82f87c310a5db3933551fd0df3d0548abf9f7c.tar.gz
zig-clap-7f82f87c310a5db3933551fd0df3d0548abf9f7c.tar.xz
zig-clap-7f82f87c310a5db3933551fd0df3d0548abf9f7c.zip
Improve Diagnostic error message reporting
Diffstat (limited to 'clap.zig')
-rw-r--r--clap.zig43
1 files changed, 27 insertions, 16 deletions
diff --git a/clap.zig b/clap.zig
index b7235f1..2eab860 100644
--- a/clap.zig
+++ b/clap.zig
@@ -289,27 +289,36 @@ pub fn Args(comptime Id: type, comptime params: []const Param(Id)) type {
289 289
290/// Optional diagnostics used for reporting useful errors 290/// Optional diagnostics used for reporting useful errors
291pub const Diagnostic = struct { 291pub const Diagnostic = struct {
292 name: Names, 292 arg: []const u8 = "",
293 name: Names = Names{},
293 294
294 /// Default diagnostics reporter when all you want is English with no colors. 295 /// Default diagnostics reporter when all you want is English with no colors.
295 /// Use this as a reference for implementing your own if needed. 296 /// Use this as a reference for implementing your own if needed.
296 pub fn report(diag: Diagnostic, stream: anytype, err: anyerror) !void { 297 pub fn report(diag: Diagnostic, stream: anytype, err: anyerror) !void {
297 const prefix = if (diag.name.short) |_| "-" else "--"; 298 const Arg = struct {
298 const name = if (diag.name.short) |*c| @as(*const [1]u8, c)[0..] else diag.name.long.?; 299 prefix: []const u8,
300 name: []const u8,
301 };
302 const a = if (diag.name.short) |*c|
303 Arg{ .prefix = "-", .name = @as(*const [1]u8, c)[0..] }
304 else if (diag.name.long) |l|
305 Arg{ .prefix = "--", .name = l }
306 else
307 Arg{ .prefix = "", .name = diag.arg };
299 308
300 switch (err) { 309 switch (err) {
301 error.DoesntTakeValue => try stream.print("The argument '{}{}' does not take a value\n", .{ prefix, name }), 310 error.DoesntTakeValue => try stream.print("The argument '{}{}' does not take a value\n", .{ a.prefix, a.name }),
302 error.MissingValue => try stream.print("The argument '{}{}' requires a value but none was supplied\n", .{ prefix, name }), 311 error.MissingValue => try stream.print("The argument '{}{}' requires a value but none was supplied\n", .{ a.prefix, a.name }),
303 error.InvalidArgument => try stream.print("Invalid argument '{}{}'\n", .{ prefix, name }), 312 error.InvalidArgument => try stream.print("Invalid argument '{}{}'\n", .{ a.prefix, a.name }),
304 else => try stream.print("Error while parsing arguments: {}\n", .{@errorName(err)}), 313 else => try stream.print("Error while parsing arguments: {}\n", .{@errorName(err)}),
305 } 314 }
306 } 315 }
307}; 316};
308 317
309fn testDiag(names: Names, err: anyerror, expected: []const u8) void { 318fn testDiag(diag: Diagnostic, err: anyerror, expected: []const u8) void {
310 var buf: [1024]u8 = undefined; 319 var buf: [1024]u8 = undefined;
311 var slice_stream = io.fixedBufferStream(&buf); 320 var slice_stream = io.fixedBufferStream(&buf);
312 (Diagnostic{ .name = names }).report(slice_stream.outStream(), err) catch unreachable; 321 diag.report(slice_stream.outStream(), err) catch unreachable;
313 322
314 const actual = slice_stream.getWritten(); 323 const actual = slice_stream.getWritten();
315 if (!mem.eql(u8, actual, expected)) { 324 if (!mem.eql(u8, actual, expected)) {
@@ -322,14 +331,16 @@ fn testDiag(names: Names, err: anyerror, expected: []const u8) void {
322} 331}
323 332
324test "Diagnostic.report" { 333test "Diagnostic.report" {
325 testDiag(.{ .short = 'c' }, error.DoesntTakeValue, "The argument '-c' does not take a value\n"); 334 testDiag(.{ .arg = "c" }, error.InvalidArgument, "Invalid argument 'c'\n");
326 testDiag(.{ .long = "cc" }, error.DoesntTakeValue, "The argument '--cc' does not take a value\n"); 335 testDiag(.{ .name = .{ .long = "cc" } }, error.InvalidArgument, "Invalid argument '--cc'\n");
327 testDiag(.{ .short = 'c' }, error.MissingValue, "The argument '-c' requires a value but none was supplied\n"); 336 testDiag(.{ .name = .{ .short = 'c' } }, error.DoesntTakeValue, "The argument '-c' does not take a value\n");
328 testDiag(.{ .long = "cc" }, error.MissingValue, "The argument '--cc' requires a value but none was supplied\n"); 337 testDiag(.{ .name = .{ .long = "cc" } }, error.DoesntTakeValue, "The argument '--cc' does not take a value\n");
329 testDiag(.{ .short = 'c' }, error.InvalidArgument, "Invalid argument '-c'\n"); 338 testDiag(.{ .name = .{ .short = 'c' } }, error.MissingValue, "The argument '-c' requires a value but none was supplied\n");
330 testDiag(.{ .long = "cc" }, error.InvalidArgument, "Invalid argument '--cc'\n"); 339 testDiag(.{ .name = .{ .long = "cc" } }, error.MissingValue, "The argument '--cc' requires a value but none was supplied\n");
331 testDiag(.{ .short = 'c' }, error.SomethingElse, "Error while parsing arguments: SomethingElse\n"); 340 testDiag(.{ .name = .{ .short = 'c' } }, error.InvalidArgument, "Invalid argument '-c'\n");
332 testDiag(.{ .long = "cc" }, error.SomethingElse, "Error while parsing arguments: SomethingElse\n"); 341 testDiag(.{ .name = .{ .long = "cc" } }, error.InvalidArgument, "Invalid argument '--cc'\n");
342 testDiag(.{ .name = .{ .short = 'c' } }, error.SomethingElse, "Error while parsing arguments: SomethingElse\n");
343 testDiag(.{ .name = .{ .long = "cc" } }, error.SomethingElse, "Error while parsing arguments: SomethingElse\n");
333} 344}
334 345
335/// Parses the command line arguments passed into the program based on an 346/// Parses the command line arguments passed into the program based on an