diff options
| author | 2020-11-03 20:04:52 +0100 | |
|---|---|---|
| committer | 2020-11-03 20:04:52 +0100 | |
| commit | c78a5dd3d751bc12013b6441b02dd67cea4c9b82 (patch) | |
| tree | dc438c005fa2daa8d1fe3f87a972380e5ffd6c53 /clap.zig | |
| parent | Report error context in Diagnostic (#26) (diff) | |
| download | zig-clap-c78a5dd3d751bc12013b6441b02dd67cea4c9b82.tar.gz zig-clap-c78a5dd3d751bc12013b6441b02dd67cea4c9b82.tar.xz zig-clap-c78a5dd3d751bc12013b6441b02dd67cea4c9b82.zip | |
Improve Diagnostic error message reporting
Diffstat (limited to 'clap.zig')
| -rw-r--r-- | clap.zig | 43 |
1 files changed, 27 insertions, 16 deletions
| @@ -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 |
| 291 | pub const Diagnostic = struct { | 291 | pub 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: var, err: anyerror) !void { | 297 | pub fn report(diag: Diagnostic, stream: var, 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 | ||
| 309 | fn testDiag(names: Names, err: anyerror, expected: []const u8) void { | 318 | fn 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 | ||
| 324 | test "Diagnostic.report" { | 333 | test "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 |