lib/tracy/src/cli/args/lock.zig

daab053ee43316e1809a84551d573ddd1e5bf3d2

  1 const std = @import("std");
  2 const tracy = @import("../../root.zig");
  3 const scalar = @import("scalar.zig");
  4 const types = @import("types.zig");
  5 
  6 pub fn parse(args: []const []const u8) !types.LockArgs {
  7     if (args.len == 0) return error.InvalidArguments;
  8     var parsed = types.LockArgs{ .path = args[0] };
  9     var around_ns: ?u64 = null;
 10     var window_ns: ?u64 = null;
 11     var index: usize = 1;
 12     while (index < args.len) : (index += 1) {
 13         if (std.mem.eql(u8, args[index], "--format")) {
 14             index += 1;
 15             if (index >= args.len) return error.InvalidArguments;
 16             if (std.mem.eql(u8, args[index], "text")) {
 17                 parsed.format = .text;
 18             } else if (std.mem.eql(u8, args[index], "jsonl")) {
 19                 parsed.format = .jsonl;
 20             } else {
 21                 return error.UnsupportedFormat;
 22             }
 23         } else if (std.mem.eql(u8, args[index], "--top")) {
 24             index += 1;
 25             if (index >= args.len) return error.InvalidArguments;
 26             parsed.options.top = try scalar.parsePositiveUsize(args[index]);
 27         } else if (std.mem.eql(u8, args[index], "--occurrences")) {
 28             index += 1;
 29             if (index >= args.len) return error.InvalidArguments;
 30             parsed.options.occurrences = try scalar.parseUsize(args[index]);
 31         } else if (std.mem.eql(u8, args[index], "--sort")) {
 32             index += 1;
 33             if (index >= args.len) return error.InvalidArguments;
 34             parsed.options.sort = tracy.locks.Sort.fromName(args[index]) orelse return error.UnsupportedSort;
 35         } else if (std.mem.eql(u8, args[index], "--kind")) {
 36             index += 1;
 37             if (index >= args.len) return error.InvalidArguments;
 38             parsed.options.kind = tracy.locks.Kind.fromName(args[index]) orelse return error.UnsupportedKind;
 39         } else if (std.mem.eql(u8, args[index], "--mode")) {
 40             index += 1;
 41             if (index >= args.len) return error.InvalidArguments;
 42             parsed.options.mode = tracy.locks.Mode.fromName(args[index]) orelse return error.UnsupportedMode;
 43         } else if (std.mem.eql(u8, args[index], "--min-wait-ns")) {
 44             index += 1;
 45             if (index >= args.len) return error.InvalidArguments;
 46             parsed.options.min_wait_ns = try scalar.parseU64(args[index]);
 47         } else if (std.mem.eql(u8, args[index], "--min-hold-ns")) {
 48             index += 1;
 49             if (index >= args.len) return error.InvalidArguments;
 50             parsed.options.min_hold_ns = try scalar.parseU64(args[index]);
 51         } else if (std.mem.eql(u8, args[index], "--lock")) {
 52             index += 1;
 53             if (index >= args.len) return error.InvalidArguments;
 54             parsed.options.lock = try scalar.parseU64(args[index]);
 55         } else if (std.mem.eql(u8, args[index], "--thread")) {
 56             index += 1;
 57             if (index >= args.len) return error.InvalidArguments;
 58             parsed.options.thread = try scalar.parseU64(args[index]);
 59         } else if (std.mem.eql(u8, args[index], "--since-ns")) {
 60             index += 1;
 61             if (index >= args.len) return error.InvalidArguments;
 62             parsed.options.since_ns = try scalar.parseU64(args[index]);
 63         } else if (std.mem.eql(u8, args[index], "--until-ns")) {
 64             index += 1;
 65             if (index >= args.len) return error.InvalidArguments;
 66             parsed.options.until_ns = try scalar.parseU64(args[index]);
 67         } else if (std.mem.eql(u8, args[index], "--around-ns")) {
 68             index += 1;
 69             if (index >= args.len) return error.InvalidArguments;
 70             around_ns = try scalar.parseU64(args[index]);
 71         } else if (std.mem.eql(u8, args[index], "--window-ns")) {
 72             index += 1;
 73             if (index >= args.len) return error.InvalidArguments;
 74             window_ns = try scalar.parseU64(args[index]);
 75         } else if (std.mem.eql(u8, args[index], "--match")) {
 76             index += 1;
 77             if (index >= args.len) return error.InvalidArguments;
 78             parsed.options.match = args[index];
 79         } else if (std.mem.eql(u8, args[index], "--ignore-case")) {
 80             parsed.options.ignore_case = true;
 81         } else {
 82             return error.UnknownArgument;
 83         }
 84     }
 85     if (around_ns) |center| {
 86         if (parsed.options.since_ns != null or parsed.options.until_ns != null) return error.InvalidArguments;
 87         const width = window_ns orelse 1_000_000;
 88         const half = width / 2;
 89         parsed.options.since_ns = if (center > half) center - half else 0;
 90         parsed.options.until_ns = center +| (width - half);
 91     } else if (window_ns != null) {
 92         return error.InvalidArguments;
 93     }
 94     if (parsed.options.since_ns != null and parsed.options.until_ns != null and parsed.options.since_ns.? > parsed.options.until_ns.?) {
 95         return error.InvalidArguments;
 96     }
 97     return parsed;
 98 }
 99 
100 test "lock args parse filters window and mode" {
101     const parsed = try parse(&.{
102         "events.jsonl",
103         "--format",
104         "jsonl",
105         "--top",
106         "12",
107         "--occurrences",
108         "4",
109         "--sort",
110         "wait-tail",
111         "--kind",
112         "wait",
113         "--mode",
114         "shared",
115         "--min-wait-ns",
116         "100",
117         "--min-hold-ns",
118         "200",
119         "--lock",
120         "3",
121         "--thread",
122         "7",
123         "--around-ns",
124         "1000",
125         "--window-ns",
126         "200",
127         "--match",
128         "queue",
129         "--ignore-case",
130     });
131     try std.testing.expectEqualStrings("events.jsonl", parsed.path);
132     try std.testing.expectEqual(types.Format.jsonl, parsed.format);
133     try std.testing.expectEqual(@as(usize, 12), parsed.options.top);
134     try std.testing.expectEqual(@as(usize, 4), parsed.options.occurrences);
135     try std.testing.expectEqual(tracy.locks.Sort.wait_tail, parsed.options.sort);
136     try std.testing.expectEqual(tracy.locks.Kind.wait, parsed.options.kind);
137     try std.testing.expectEqual(tracy.locks.Mode.shared, parsed.options.mode);
138     try std.testing.expectEqual(@as(u64, 100), parsed.options.min_wait_ns);
139     try std.testing.expectEqual(@as(u64, 200), parsed.options.min_hold_ns);
140     try std.testing.expectEqual(@as(?u64, 3), parsed.options.lock);
141     try std.testing.expectEqual(@as(?u64, 7), parsed.options.thread);
142     try std.testing.expectEqual(@as(?u64, 900), parsed.options.since_ns);
143     try std.testing.expectEqual(@as(?u64, 1100), parsed.options.until_ns);
144     try std.testing.expectEqualStrings("queue", parsed.options.match.?);
145     try std.testing.expect(parsed.options.ignore_case);
146 }