options.zig (2479B)
1 const std = @import("std"); 2 3 pub const OptionsTag = enum { settings, help }; 4 5 pub const Options = union(OptionsTag) { 6 settings: Settings, 7 help: void, 8 }; 9 10 pub const Settings = struct { 11 task_length: u32 = 26, 12 task_break: u32 = 4, 13 notifications: bool = true, 14 file: ?[]const u8 = null, 15 }; 16 17 pub fn parseArgs(args: []const []const u8) !Options { 18 var settings = Settings{}; 19 20 var i: u32 = 0; 21 while (i < args.len) : (i += 1) { 22 const arg = args[i]; 23 if (i + 1 < args.len and std.mem.eql(u8, arg, "-t")) { 24 i += 1; 25 settings.task_length = try std.fmt.parseInt(u32, args[i], 10); 26 } else if (i + 1 < args.len and std.mem.eql(u8, arg, "-b")) { 27 i += 1; 28 settings.task_break = try std.fmt.parseInt(u32, args[i], 10); 29 } else if (std.mem.eql(u8, arg, "-s")) { 30 settings.notifications = false; 31 } else if (i + 1 < args.len and std.mem.eql(u8, arg, "--file")) { 32 i += 1; 33 settings.file = args[i]; 34 } else if (std.mem.eql(u8, arg, "-h")) { 35 return .{ .help = void{} }; 36 } else { 37 return error.InvalidArgument; 38 } 39 } 40 41 return .{ .settings = settings }; 42 } 43 44 pub fn usage(allocator: std.mem.Allocator, program: []const u8) ![]u8 { 45 const result = try std.fmt.allocPrint(allocator, 46 \\Usage: {s} 47 \\[-t <task_length>] Task length in minutes (default: 26 mins) 48 \\[-b <task_break>] Task break length in minutes (default: 4 mins) 49 \\[-s] Disable notifications 50 \\[--file <path>] Write status to a file 51 \\[-h] Show this help message 52 \\ 53 , .{program}); 54 55 return result; 56 } 57 58 test "parseArgs options" { 59 const args = [_][]const u8{ 60 "-t", "30", 61 "-b", "20", 62 "-s", 63 }; 64 65 const options = try parseArgs(&args); 66 try std.testing.expectEqual(options.settings.task_length, 30); 67 try std.testing.expectEqual(options.settings.task_break, 20); 68 try std.testing.expectEqual(options.settings.notifications, false); 69 } 70 71 test "parseArgs help" { 72 const args = [_][]const u8{"-h"}; 73 74 const options = try parseArgs(&args); 75 try std.testing.expectEqual(options, OptionsTag.help); 76 } 77 78 test "parseArgs nok" { 79 const args = [_][]const u8{ "some", "junk", "arguments" }; 80 81 const result = parseArgs(&args); 82 try std.testing.expectError(error.InvalidArgument, result); 83 }