summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--build.zig5
-rw-r--r--src/core.zig65
-rw-r--r--src/extended.zig51
-rw-r--r--tests/core.zig136
-rw-r--r--tests/extended.zig68
5 files changed, 148 insertions, 177 deletions
diff --git a/build.zig b/build.zig
index 29792ee..6ec8837 100644
--- a/build.zig
+++ b/build.zig
@@ -5,7 +5,7 @@ pub fn build(b: *Builder) void {
5 5
6 { 6 {
7 const example_step = b.step("examples", "Build all examples"); 7 const example_step = b.step("examples", "Build all examples");
8 const examples = [][]const u8 {}; 8 const examples = [][]const u8{};
9 9
10 b.default_step.dependOn(example_step); 10 b.default_step.dependOn(example_step);
11 inline for (examples) |example| { 11 inline for (examples) |example| {
@@ -22,7 +22,7 @@ pub fn build(b: *Builder) void {
22 22
23 { 23 {
24 const test_step = b.step("tests", "Run all tests"); 24 const test_step = b.step("tests", "Run all tests");
25 const tests = [][]const u8 { 25 const tests = [][]const u8{
26 "core", 26 "core",
27 "extended", 27 "extended",
28 }; 28 };
@@ -38,6 +38,5 @@ pub fn build(b: *Builder) void {
38 step.dependOn(&t.step); 38 step.dependOn(&t.step);
39 test_step.dependOn(step); 39 test_step.dependOn(step);
40 } 40 }
41
42 } 41 }
43} 42}
diff --git a/src/core.zig b/src/core.zig
index d870e8c..a0f794c 100644
--- a/src/core.zig
+++ b/src/core.zig
@@ -102,12 +102,10 @@ pub fn Param(comptime Id: type) type {
102 pub fn init(id: Id, takes_value: bool, names: *const Names) Self { 102 pub fn init(id: Id, takes_value: bool, names: *const Names) Self {
103 // Assert, that if the param have no name, then it has to take 103 // Assert, that if the param have no name, then it has to take
104 // a value. 104 // a value.
105 debug.assert( 105 debug.assert(names.bare != null or
106 names.bare != null or
107 names.long != null or 106 names.long != null or
108 names.short != null or 107 names.short != null or
109 takes_value 108 takes_value);
110 );
111 109
112 return Self{ 110 return Self{
113 .id = id, 111 .id = id,
@@ -127,7 +125,7 @@ pub fn Arg(comptime Id: type) type {
127 value: ?[]const u8, 125 value: ?[]const u8,
128 126
129 pub fn init(param: *const Param(Id), value: ?[]const u8) Self { 127 pub fn init(param: *const Param(Id), value: ?[]const u8) Self {
130 return Self { 128 return Self{
131 .param = param, 129 .param = param,
132 .value = value, 130 .value = value,
133 }; 131 };
@@ -141,7 +139,7 @@ pub fn ArgIterator(comptime E: type) type {
141 const Self = this; 139 const Self = this;
142 const Error = E; 140 const Error = E;
143 141
144 nextFn: fn(iter: *Self) Error!?[]const u8, 142 nextFn: fn (iter: *Self) Error!?[]const u8,
145 143
146 pub fn next(iter: *Self) Error!?[]const u8 { 144 pub fn next(iter: *Self) Error!?[]const u8 {
147 return iter.nextFn(iter); 145 return iter.nextFn(iter);
@@ -159,12 +157,10 @@ pub const ArgSliceIterator = struct {
159 iter: ArgIterator(Error), 157 iter: ArgIterator(Error),
160 158
161 pub fn init(args: []const []const u8) ArgSliceIterator { 159 pub fn init(args: []const []const u8) ArgSliceIterator {
162 return ArgSliceIterator { 160 return ArgSliceIterator{
163 .args = args, 161 .args = args,
164 .index = 0, 162 .index = 0,
165 .iter = ArgIterator(Error) { 163 .iter = ArgIterator(Error){ .nextFn = nextFn },
166 .nextFn = nextFn,
167 },
168 }; 164 };
169 } 165 }
170 166
@@ -188,12 +184,10 @@ pub const OsArgIterator = struct {
188 iter: ArgIterator(Error), 184 iter: ArgIterator(Error),
189 185
190 pub fn init(allocator: *mem.Allocator) OsArgIterator { 186 pub fn init(allocator: *mem.Allocator) OsArgIterator {
191 return OsArgIterator { 187 return OsArgIterator{
192 .arena = heap.ArenaAllocator.init(allocator), 188 .arena = heap.ArenaAllocator.init(allocator),
193 .args = os.args(), 189 .args = os.args(),
194 .iter = ArgIterator(Error) { 190 .iter = ArgIterator(Error){ .nextFn = nextFn },
195 .nextFn = nextFn,
196 },
197 }; 191 };
198 } 192 }
199 193
@@ -204,7 +198,7 @@ pub const OsArgIterator = struct {
204 fn nextFn(iter: *ArgIterator(Error)) Error!?[]const u8 { 198 fn nextFn(iter: *ArgIterator(Error)) Error!?[]const u8 {
205 const self = @fieldParentPtr(OsArgIterator, "iter", iter); 199 const self = @fieldParentPtr(OsArgIterator, "iter", iter);
206 if (builtin.os == builtin.Os.windows) { 200 if (builtin.os == builtin.Os.windows) {
207 return try self.args.next(self.allocator) ?? return null; 201 return try self.args.next(self.allocator) orelse return null;
208 } else { 202 } else {
209 return self.args.nextPosix(); 203 return self.args.nextPosix();
210 } 204 }
@@ -233,7 +227,7 @@ pub fn Clap(comptime Id: type, comptime ArgError: type) type {
233 state: State, 227 state: State,
234 228
235 pub fn init(params: []const Param(Id), iter: *ArgIterator(ArgError)) Self { 229 pub fn init(params: []const Param(Id), iter: *ArgIterator(ArgError)) Self {
236 var res = Self { 230 var res = Self{
237 .params = params, 231 .params = params,
238 .iter = iter, 232 .iter = iter,
239 .state = State.Normal, 233 .state = State.Normal,
@@ -245,7 +239,11 @@ pub fn Clap(comptime Id: type, comptime ArgError: type) type {
245 /// Get the next ::Arg that matches a ::Param. 239 /// Get the next ::Arg that matches a ::Param.
246 pub fn next(clap: *Self) !?Arg(Id) { 240 pub fn next(clap: *Self) !?Arg(Id) {
247 const ArgInfo = struct { 241 const ArgInfo = struct {
248 const Kind = enum { Long, Short, Bare }; 242 const Kind = enum {
243 Long,
244 Short,
245 Bare,
246 };
249 247
250 arg: []const u8, 248 arg: []const u8,
251 kind: Kind, 249 kind: Kind,
@@ -253,7 +251,7 @@ pub fn Clap(comptime Id: type, comptime ArgError: type) type {
253 251
254 switch (clap.state) { 252 switch (clap.state) {
255 State.Normal => { 253 State.Normal => {
256 const full_arg = (try clap.iter.next()) ?? return null; 254 const full_arg = (try clap.iter.next()) orelse return null;
257 const arg_info = blk: { 255 const arg_info = blk: {
258 var arg = full_arg; 256 var arg = full_arg;
259 var kind = ArgInfo.Kind.Bare; 257 var kind = ArgInfo.Kind.Bare;
@@ -271,7 +269,7 @@ pub fn Clap(comptime Id: type, comptime ArgError: type) type {
271 if (kind != ArgInfo.Kind.Long and arg.len == 0) 269 if (kind != ArgInfo.Kind.Long and arg.len == 0)
272 return error.InvalidArgument; 270 return error.InvalidArgument;
273 271
274 break :blk ArgInfo { .arg = arg, .kind = kind }; 272 break :blk ArgInfo{ .arg = arg, .kind = kind };
275 }; 273 };
276 274
277 const arg = arg_info.arg; 275 const arg = arg_info.arg;
@@ -279,16 +277,15 @@ pub fn Clap(comptime Id: type, comptime ArgError: type) type {
279 const eql_index = mem.indexOfScalar(u8, arg, '='); 277 const eql_index = mem.indexOfScalar(u8, arg, '=');
280 278
281 switch (kind) { 279 switch (kind) {
282 ArgInfo.Kind.Bare, 280 ArgInfo.Kind.Bare, ArgInfo.Kind.Long => {
283 ArgInfo.Kind.Long => {
284 for (clap.params) |*param| { 281 for (clap.params) |*param| {
285 const match = switch (kind) { 282 const match = switch (kind) {
286 ArgInfo.Kind.Bare => param.names.bare ?? continue, 283 ArgInfo.Kind.Bare => param.names.bare orelse continue,
287 ArgInfo.Kind.Long => param.names.long ?? continue, 284 ArgInfo.Kind.Long => param.names.long orelse continue,
288 else => unreachable, 285 else => unreachable,
289 }; 286 };
290 const name = if (eql_index) |i| arg[0..i] else arg; 287 const name = if (eql_index) |i| arg[0..i] else arg;
291 const maybe_value = if (eql_index) |i| arg[i + 1..] else null; 288 const maybe_value = if (eql_index) |i| arg[i + 1 ..] else null;
292 289
293 if (!mem.eql(u8, name, match)) 290 if (!mem.eql(u8, name, match))
294 continue; 291 continue;
@@ -303,14 +300,14 @@ pub fn Clap(comptime Id: type, comptime ArgError: type) type {
303 if (maybe_value) |v| 300 if (maybe_value) |v|
304 break :blk v; 301 break :blk v;
305 302
306 break :blk (try clap.iter.next()) ?? return error.MissingValue; 303 break :blk (try clap.iter.next()) orelse return error.MissingValue;
307 }; 304 };
308 305
309 return Arg(Id).init(param, value); 306 return Arg(Id).init(param, value);
310 } 307 }
311 }, 308 },
312 ArgInfo.Kind.Short => { 309 ArgInfo.Kind.Short => {
313 return try clap.chainging(State.Chaining { 310 return try clap.chainging(State.Chaining{
314 .arg = full_arg, 311 .arg = full_arg,
315 .index = (full_arg.len - arg.len), 312 .index = (full_arg.len - arg.len),
316 }); 313 });
@@ -340,7 +337,7 @@ pub fn Clap(comptime Id: type, comptime ArgError: type) type {
340 const next_index = index + 1; 337 const next_index = index + 1;
341 338
342 for (clap.params) |*param| { 339 for (clap.params) |*param| {
343 const short = param.names.short ?? continue; 340 const short = param.names.short orelse continue;
344 if (short != arg[index]) 341 if (short != arg[index])
345 continue; 342 continue;
346 343
@@ -349,10 +346,12 @@ pub fn Clap(comptime Id: type, comptime ArgError: type) type {
349 if (arg.len <= next_index or param.takes_value) { 346 if (arg.len <= next_index or param.takes_value) {
350 clap.state = State.Normal; 347 clap.state = State.Normal;
351 } else { 348 } else {
352 clap.state = State { .Chaining = State.Chaining { 349 clap.state = State{
353 .arg = arg, 350 .Chaining = State.Chaining{
354 .index = next_index, 351 .arg = arg,
355 }}; 352 .index = next_index,
353 },
354 };
356 } 355 }
357 } 356 }
358 357
@@ -360,12 +359,12 @@ pub fn Clap(comptime Id: type, comptime ArgError: type) type {
360 return Arg(Id).init(param, null); 359 return Arg(Id).init(param, null);
361 360
362 if (arg.len <= next_index) { 361 if (arg.len <= next_index) {
363 const value = (try clap.iter.next()) ?? return error.MissingValue; 362 const value = (try clap.iter.next()) orelse return error.MissingValue;
364 return Arg(Id).init(param, value); 363 return Arg(Id).init(param, value);
365 } 364 }
366 365
367 if (arg[next_index] == '=') { 366 if (arg[next_index] == '=') {
368 return Arg(Id).init(param, arg[next_index + 1..]); 367 return Arg(Id).init(param, arg[next_index + 1 ..]);
369 } 368 }
370 369
371 return Arg(Id).init(param, arg[next_index..]); 370 return Arg(Id).init(param, arg[next_index..]);
diff --git a/src/extended.zig b/src/extended.zig
index ec8310e..09e91dd 100644
--- a/src/extended.zig
+++ b/src/extended.zig
@@ -1,12 +1,12 @@
1pub const core = @import("core.zig"); 1pub const core = @import("core.zig");
2 2
3const builtin = @import("builtin"); 3const builtin = @import("builtin");
4const std = @import("std"); 4const std = @import("std");
5 5
6const mem = std.mem; 6const mem = std.mem;
7const fmt = std.fmt; 7const fmt = std.fmt;
8const debug = std.debug; 8const debug = std.debug;
9const io = std.io; 9const io = std.io;
10 10
11const assert = debug.assert; 11const assert = debug.assert;
12 12
@@ -92,7 +92,7 @@ pub const Parser = struct {
92 func: UnsafeFunction, 92 func: UnsafeFunction,
93 93
94 pub fn init(comptime FieldType: type, comptime Errors: type, func: ParseFunc(FieldType, Errors)) Parser { 94 pub fn init(comptime FieldType: type, comptime Errors: type, func: ParseFunc(FieldType, Errors)) Parser {
95 return Parser { 95 return Parser{
96 .FieldType = FieldType, 96 .FieldType = FieldType,
97 .Errors = Errors, 97 .Errors = Errors,
98 .func = @ptrCast(UnsafeFunction, func), 98 .func = @ptrCast(UnsafeFunction, func),
@@ -104,7 +104,7 @@ pub const Parser = struct {
104 } 104 }
105 105
106 fn ParseFunc(comptime FieldType: type, comptime Errors: type) type { 106 fn ParseFunc(comptime FieldType: type, comptime Errors: type) type {
107 return fn(*FieldType, []const u8) Errors!void; 107 return fn (*FieldType, []const u8) Errors!void;
108 } 108 }
109 109
110 pub fn int(comptime Int: type, comptime radix: u8) Parser { 110 pub fn int(comptime Int: type, comptime radix: u8) Parser {
@@ -113,22 +113,14 @@ pub const Parser = struct {
113 field_ptr.* = try fmt.parseInt(Int, arg, radix); 113 field_ptr.* = try fmt.parseInt(Int, arg, radix);
114 } 114 }
115 }.i; 115 }.i;
116 return Parser.init( 116 return Parser.init(Int, @typeOf(func).ReturnType.ErrorSet, func);
117 Int,
118 @typeOf(func).ReturnType.ErrorSet,
119 func
120 );
121 } 117 }
122 118
123 const string = Parser.init( 119 const string = Parser.init([]const u8, error{}, struct {
124 []const u8, 120 fn s(field_ptr: *[]const u8, arg: []const u8) (error{}!void) {
125 error{}, 121 field_ptr.* = arg;
126 struct { 122 }
127 fn s(field_ptr: *[]const u8, arg: []const u8) (error{}!void) { 123 }.s);
128 field_ptr.* = arg;
129 }
130 }.s
131 );
132}; 124};
133 125
134pub fn Clap(comptime Result: type) type { 126pub fn Clap(comptime Result: type) type {
@@ -174,7 +166,7 @@ pub fn Clap(comptime Result: type) type {
174 166
175 for (command.params) |p, i| { 167 for (command.params) |p, i| {
176 const id = i; 168 const id = i;
177 res[id] = core.Param(usize) { 169 res[id] = core.Param(usize){
178 .id = id, 170 .id = id,
179 .takes_value = p.kind == Param.Kind.Option, 171 .takes_value = p.kind == Param.Kind.Option,
180 .names = p.names, 172 .names = p.names,
@@ -186,10 +178,9 @@ pub fn Clap(comptime Result: type) type {
186 178
187 var pos: usize = 0; 179 var pos: usize = 0;
188 180
189 arg_loop: 181 arg_loop: while (try clap.next()) |arg| : (pos += 1) {
190 while (try clap.next()) |arg| : (pos += 1) { 182 inline for (command.params) |param, i| {
191 inline for(command.params) |param, i| { 183 if (arg.param.id == i and (param.settings.position orelse pos) == pos) {
192 if (arg.param.id == i and (param.settings.position ?? pos) == pos) {
193 handled[i] = true; 184 handled[i] = true;
194 185
195 switch (param.kind) { 186 switch (param.kind) {
@@ -197,7 +188,7 @@ pub fn Clap(comptime Result: type) type {
197 getFieldPtr(&result, param.field).* = true; 188 getFieldPtr(&result, param.field).* = true;
198 }, 189 },
199 Param.Kind.Option => |parser| { 190 Param.Kind.Option => |parser| {
200 try parser.parse(getFieldPtr(&result, param.field), ??arg.value); 191 try parser.parse(getFieldPtr(&result, param.field), arg.value.?);
201 }, 192 },
202 Param.Kind.Subcommand => |sub_command| { 193 Param.Kind.Subcommand => |sub_command| {
203 getFieldPtr(&result, param.field).* = try sub_command.parseHelper(Error, clap); 194 getFieldPtr(&result, param.field).* = try sub_command.parseHelper(Error, clap);
@@ -223,19 +214,19 @@ pub fn Clap(comptime Result: type) type {
223 214
224 fn GetFieldPtrReturn(comptime Struct: type, comptime field: []const u8) type { 215 fn GetFieldPtrReturn(comptime Struct: type, comptime field: []const u8) type {
225 var inst: Struct = undefined; 216 var inst: Struct = undefined;
226 const dot_index = comptime mem.indexOfScalar(u8, field, '.') ?? { 217 const dot_index = comptime mem.indexOfScalar(u8, field, '.') orelse {
227 return @typeOf(&@field(inst, field)); 218 return @typeOf(&@field(inst, field));
228 }; 219 };
229 220
230 return GetFieldPtrReturn(@typeOf(@field(inst, field[0..dot_index])), field[dot_index + 1..]); 221 return GetFieldPtrReturn(@typeOf(@field(inst, field[0..dot_index])), field[dot_index + 1 ..]);
231 } 222 }
232 223
233 fn getFieldPtr(curr: var, comptime field: []const u8) GetFieldPtrReturn(@typeOf(curr).Child, field) { 224 fn getFieldPtr(curr: var, comptime field: []const u8) GetFieldPtrReturn(@typeOf(curr).Child, field) {
234 const dot_index = comptime mem.indexOfScalar(u8, field, '.') ?? { 225 const dot_index = comptime mem.indexOfScalar(u8, field, '.') orelse {
235 return &@field(curr, field); 226 return &@field(curr, field);
236 }; 227 };
237 228
238 return getFieldPtr(&@field(curr, field[0..dot_index]), field[dot_index + 1..]); 229 return getFieldPtr(&@field(curr, field[0..dot_index]), field[dot_index + 1 ..]);
239 } 230 }
240 }; 231 };
241} 232}
diff --git a/tests/core.zig b/tests/core.zig
index 91b62fe..765b161 100644
--- a/tests/core.zig
+++ b/tests/core.zig
@@ -19,116 +19,102 @@ fn testNoErr(params: []const Param(u8), args: []const []const u8, ids: []const u
19 var i: usize = 0; 19 var i: usize = 0;
20 while (iter.next() catch unreachable) |arg| : (i += 1) { 20 while (iter.next() catch unreachable) |arg| : (i += 1) {
21 debug.assert(ids[i] == arg.param.id); 21 debug.assert(ids[i] == arg.param.id);
22 const expected_value = values[i] ?? { 22 const expected_value = values[i] orelse {
23 debug.assert(arg.value == null); 23 debug.assert(arg.value == null);
24 continue; 24 continue;
25 }; 25 };
26 const actual_value = arg.value ?? unreachable; 26 const actual_value = arg.value orelse unreachable;
27 27
28 debug.assert(mem.eql(u8, expected_value, actual_value)); 28 debug.assert(mem.eql(u8, expected_value, actual_value));
29 } 29 }
30} 30}
31 31
32test "clap.core: short" { 32test "clap.core: short" {
33 const params = []Param(u8) { 33 const params = []Param(u8){
34 Param(u8).init(0, false, Names.short('a')), 34 Param(u8).init(0, false, Names.short('a')),
35 Param(u8).init(1, false, Names.short('b')), 35 Param(u8).init(1, false, Names.short('b')),
36 Param(u8).init(2, true, Names.short('c')), 36 Param(u8).init(2, true, Names.short('c')),
37 }; 37 };
38 38
39 testNoErr(params, [][]const u8 { "-a" }, []u8{0}, []?[]const u8{null}); 39 testNoErr(params, [][]const u8{"-a"}, []u8{0}, []?[]const u8{null});
40 testNoErr(params, [][]const u8 { "-a", "-b" }, []u8{0,1}, []?[]const u8{null,null}); 40 testNoErr(params, [][]const u8{ "-a", "-b" }, []u8{ 0, 1 }, []?[]const u8{ null, null });
41 testNoErr(params, [][]const u8 { "-ab" }, []u8{0,1}, []?[]const u8{null,null}); 41 testNoErr(params, [][]const u8{"-ab"}, []u8{ 0, 1 }, []?[]const u8{ null, null });
42 testNoErr(params, [][]const u8 { "-c=100" }, []u8{2}, []?[]const u8{"100"}); 42 testNoErr(params, [][]const u8{"-c=100"}, []u8{2}, []?[]const u8{"100"});
43 testNoErr(params, [][]const u8 { "-c100" }, []u8{2}, []?[]const u8{"100"}); 43 testNoErr(params, [][]const u8{"-c100"}, []u8{2}, []?[]const u8{"100"});
44 testNoErr(params, [][]const u8 { "-c", "100" }, []u8{2}, []?[]const u8{"100"}); 44 testNoErr(params, [][]const u8{ "-c", "100" }, []u8{2}, []?[]const u8{"100"});
45 testNoErr(params, [][]const u8 { "-abc", "100" }, []u8{0,1,2}, []?[]const u8{null,null,"100"}); 45 testNoErr(params, [][]const u8{ "-abc", "100" }, []u8{ 0, 1, 2 }, []?[]const u8{ null, null, "100" });
46 testNoErr(params, [][]const u8 { "-abc=100" }, []u8{0,1,2}, []?[]const u8{null,null,"100"}); 46 testNoErr(params, [][]const u8{"-abc=100"}, []u8{ 0, 1, 2 }, []?[]const u8{ null, null, "100" });
47 testNoErr(params, [][]const u8 { "-abc100" }, []u8{0,1,2}, []?[]const u8{null,null,"100"}); 47 testNoErr(params, [][]const u8{"-abc100"}, []u8{ 0, 1, 2 }, []?[]const u8{ null, null, "100" });
48} 48}
49 49
50test "clap.core: long" { 50test "clap.core: long" {
51 const params = []Param(u8) { 51 const params = []Param(u8){
52 Param(u8).init(0, false, Names.long("aa")), 52 Param(u8).init(0, false, Names.long("aa")),
53 Param(u8).init(1, false, Names.long("bb")), 53 Param(u8).init(1, false, Names.long("bb")),
54 Param(u8).init(2, true, Names.long("cc")), 54 Param(u8).init(2, true, Names.long("cc")),
55 }; 55 };
56 56
57 testNoErr(params, [][]const u8 { "--aa" }, []u8{0}, []?[]const u8{null}); 57 testNoErr(params, [][]const u8{"--aa"}, []u8{0}, []?[]const u8{null});
58 testNoErr(params, [][]const u8 { "--aa", "--bb" }, []u8{0,1}, []?[]const u8{null,null}); 58 testNoErr(params, [][]const u8{ "--aa", "--bb" }, []u8{ 0, 1 }, []?[]const u8{ null, null });
59 testNoErr(params, [][]const u8 { "--cc=100" }, []u8{2}, []?[]const u8{"100"}); 59 testNoErr(params, [][]const u8{"--cc=100"}, []u8{2}, []?[]const u8{"100"});
60 testNoErr(params, [][]const u8 { "--cc", "100" }, []u8{2}, []?[]const u8{"100"}); 60 testNoErr(params, [][]const u8{ "--cc", "100" }, []u8{2}, []?[]const u8{"100"});
61} 61}
62 62
63test "clap.core: bare" { 63test "clap.core: bare" {
64 const params = []Param(u8) { 64 const params = []Param(u8){
65 Param(u8).init(0, false, Names.bare("aa")), 65 Param(u8).init(0, false, Names.bare("aa")),
66 Param(u8).init(1, false, Names.bare("bb")), 66 Param(u8).init(1, false, Names.bare("bb")),
67 Param(u8).init(2, true, Names.bare("cc")), 67 Param(u8).init(2, true, Names.bare("cc")),
68 }; 68 };
69 69
70 testNoErr(params, [][]const u8 { "aa" }, []u8{0}, []?[]const u8{null}); 70 testNoErr(params, [][]const u8{"aa"}, []u8{0}, []?[]const u8{null});
71 testNoErr(params, [][]const u8 { "aa", "bb" }, []u8{0,1}, []?[]const u8{null,null}); 71 testNoErr(params, [][]const u8{ "aa", "bb" }, []u8{ 0, 1 }, []?[]const u8{ null, null });
72 testNoErr(params, [][]const u8 { "cc=100" }, []u8{2}, []?[]const u8{"100"}); 72 testNoErr(params, [][]const u8{"cc=100"}, []u8{2}, []?[]const u8{"100"});
73 testNoErr(params, [][]const u8 { "cc", "100" }, []u8{2}, []?[]const u8{"100"}); 73 testNoErr(params, [][]const u8{ "cc", "100" }, []u8{2}, []?[]const u8{"100"});
74} 74}
75 75
76test "clap.core: none" { 76test "clap.core: none" {
77 const params = []Param(u8) { 77 const params = []Param(u8){Param(u8).init(0, true, Names.none())};
78 Param(u8).init(0, true, Names.none()),
79 };
80 78
81 testNoErr(params, [][]const u8 { "aa" }, []u8{0}, []?[]const u8{"aa"}); 79 testNoErr(params, [][]const u8{"aa"}, []u8{0}, []?[]const u8{"aa"});
82} 80}
83 81
84test "clap.core: all" { 82test "clap.core: all" {
85 const params = []Param(u8) { 83 const params = []Param(u8){
86 Param(u8).init( 84 Param(u8).init(0, false, Names{
87 0, 85 .bare = "aa",
88 false, 86 .short = 'a',
89 Names{ 87 .long = "aa",
90 .bare = "aa", 88 }),
91 .short = 'a', 89 Param(u8).init(1, false, Names{
92 .long = "aa", 90 .bare = "bb",
93 } 91 .short = 'b',
94 ), 92 .long = "bb",
95 Param(u8).init( 93 }),
96 1, 94 Param(u8).init(2, true, Names{
97 false, 95 .bare = "cc",
98 Names{ 96 .short = 'c',
99 .bare = "bb", 97 .long = "cc",
100 .short = 'b', 98 }),
101 .long = "bb",
102 }
103 ),
104 Param(u8).init(
105 2,
106 true,
107 Names{
108 .bare = "cc",
109 .short = 'c',
110 .long = "cc",
111 }
112 ),
113 Param(u8).init(3, true, Names.none()), 99 Param(u8).init(3, true, Names.none()),
114 }; 100 };
115 101
116 testNoErr(params, [][]const u8 { "-a" }, []u8{0}, []?[]const u8{null}); 102 testNoErr(params, [][]const u8{"-a"}, []u8{0}, []?[]const u8{null});
117 testNoErr(params, [][]const u8 { "-a", "-b" }, []u8{0,1}, []?[]const u8{null,null}); 103 testNoErr(params, [][]const u8{ "-a", "-b" }, []u8{ 0, 1 }, []?[]const u8{ null, null });
118 testNoErr(params, [][]const u8 { "-ab" }, []u8{0,1}, []?[]const u8{null,null}); 104 testNoErr(params, [][]const u8{"-ab"}, []u8{ 0, 1 }, []?[]const u8{ null, null });
119 testNoErr(params, [][]const u8 { "-c=100" }, []u8{2}, []?[]const u8{"100"}); 105 testNoErr(params, [][]const u8{"-c=100"}, []u8{2}, []?[]const u8{"100"});
120 testNoErr(params, [][]const u8 { "-c100" }, []u8{2}, []?[]const u8{"100"}); 106 testNoErr(params, [][]const u8{"-c100"}, []u8{2}, []?[]const u8{"100"});
121 testNoErr(params, [][]const u8 { "-c", "100" }, []u8{2}, []?[]const u8{"100"}); 107 testNoErr(params, [][]const u8{ "-c", "100" }, []u8{2}, []?[]const u8{"100"});
122 testNoErr(params, [][]const u8 { "-abc", "100" }, []u8{0,1,2}, []?[]const u8{null,null,"100"}); 108 testNoErr(params, [][]const u8{ "-abc", "100" }, []u8{ 0, 1, 2 }, []?[]const u8{ null, null, "100" });
123 testNoErr(params, [][]const u8 { "-abc=100" }, []u8{0,1,2}, []?[]const u8{null,null,"100"}); 109 testNoErr(params, [][]const u8{"-abc=100"}, []u8{ 0, 1, 2 }, []?[]const u8{ null, null, "100" });
124 testNoErr(params, [][]const u8 { "-abc100" }, []u8{0,1,2}, []?[]const u8{null,null,"100"}); 110 testNoErr(params, [][]const u8{"-abc100"}, []u8{ 0, 1, 2 }, []?[]const u8{ null, null, "100" });
125 testNoErr(params, [][]const u8 { "--aa" }, []u8{0}, []?[]const u8{null}); 111 testNoErr(params, [][]const u8{"--aa"}, []u8{0}, []?[]const u8{null});
126 testNoErr(params, [][]const u8 { "--aa", "--bb" }, []u8{0,1}, []?[]const u8{null,null}); 112 testNoErr(params, [][]const u8{ "--aa", "--bb" }, []u8{ 0, 1 }, []?[]const u8{ null, null });
127 testNoErr(params, [][]const u8 { "--cc=100" }, []u8{2}, []?[]const u8{"100"}); 113 testNoErr(params, [][]const u8{"--cc=100"}, []u8{2}, []?[]const u8{"100"});
128 testNoErr(params, [][]const u8 { "--cc", "100" }, []u8{2}, []?[]const u8{"100"}); 114 testNoErr(params, [][]const u8{ "--cc", "100" }, []u8{2}, []?[]const u8{"100"});
129 testNoErr(params, [][]const u8 { "aa" }, []u8{0}, []?[]const u8{null}); 115 testNoErr(params, [][]const u8{"aa"}, []u8{0}, []?[]const u8{null});
130 testNoErr(params, [][]const u8 { "aa", "bb" }, []u8{0,1}, []?[]const u8{null,null}); 116 testNoErr(params, [][]const u8{ "aa", "bb" }, []u8{ 0, 1 }, []?[]const u8{ null, null });
131 testNoErr(params, [][]const u8 { "cc=100" }, []u8{2}, []?[]const u8{"100"}); 117 testNoErr(params, [][]const u8{"cc=100"}, []u8{2}, []?[]const u8{"100"});
132 testNoErr(params, [][]const u8 { "cc", "100" }, []u8{2}, []?[]const u8{"100"}); 118 testNoErr(params, [][]const u8{ "cc", "100" }, []u8{2}, []?[]const u8{"100"});
133 testNoErr(params, [][]const u8 { "dd" }, []u8{3}, []?[]const u8{"dd"}); 119 testNoErr(params, [][]const u8{"dd"}, []u8{3}, []?[]const u8{"dd"});
134} 120}
diff --git a/tests/extended.zig b/tests/extended.zig
index 78c319e..3dbb87d 100644
--- a/tests/extended.zig
+++ b/tests/extended.zig
@@ -29,18 +29,14 @@ pub fn Test(comptime Expect: type) type {
29 pub fn success(args: []const []const u8, expected: *const Expect) Self { 29 pub fn success(args: []const []const u8, expected: *const Expect) Self {
30 return Self{ 30 return Self{
31 .args = args, 31 .args = args,
32 .kind = Kind{ 32 .kind = Kind{ .Success = expected.* },
33 .Success = expected.*,
34 },
35 }; 33 };
36 } 34 }
37 35
38 pub fn fail(args: []const []const u8, err: error) Self { 36 pub fn fail(args: []const []const u8, err: error) Self {
39 return Self{ 37 return Self{
40 .args = args, 38 .args = args,
41 .kind = Kind{ 39 .kind = Kind{ .Fail = err },
42 .Fail = err,
43 },
44 }; 40 };
45 } 41 }
46 42
@@ -86,74 +82,74 @@ test "clap.extended: short" {
86 break :p res; 82 break :p res;
87 }, 83 },
88 Param.option("b", Names.short('b'), &Parser.int(u8, 10)), 84 Param.option("b", Names.short('b'), &Parser.int(u8, 10)),
89 } 85 },
90 }; 86 };
91 87
92 const T = Test(S); 88 const T = Test(S);
93 const tests = []T{ 89 const tests = []T{
94 T.success( 90 T.success(
95 [][]const u8 { "-a" }, 91 [][]const u8{"-a"},
96 S{ 92 S{
97 .a = true, 93 .a = true,
98 .b = 0, 94 .b = 0,
99 }, 95 },
100 ), 96 ),
101 T.success( 97 T.success(
102 [][]const u8 { "-a", "-b", "100" }, 98 [][]const u8{ "-a", "-b", "100" },
103 S{ 99 S{
104 .a = true, 100 .a = true,
105 .b = 100, 101 .b = 100,
106 }, 102 },
107 ), 103 ),
108 T.success( 104 T.success(
109 [][]const u8 { "-a", "-b=100" }, 105 [][]const u8{ "-a", "-b=100" },
110 S{ 106 S{
111 .a = true, 107 .a = true,
112 .b = 100, 108 .b = 100,
113 }, 109 },
114 ), 110 ),
115 T.success( 111 T.success(
116 [][]const u8 { "-a", "-b100" }, 112 [][]const u8{ "-a", "-b100" },
117 S{ 113 S{
118 .a = true, 114 .a = true,
119 .b = 100, 115 .b = 100,
120 }, 116 },
121 ), 117 ),
122 T.success( 118 T.success(
123 [][]const u8 { "-ab", "100" }, 119 [][]const u8{ "-ab", "100" },
124 S{ 120 S{
125 .a = true, 121 .a = true,
126 .b = 100, 122 .b = 100,
127 }, 123 },
128 ), 124 ),
129 T.success( 125 T.success(
130 [][]const u8 { "-ab=100" }, 126 [][]const u8{"-ab=100"},
131 S{ 127 S{
132 .a = true, 128 .a = true,
133 .b = 100, 129 .b = 100,
134 }, 130 },
135 ), 131 ),
136 T.success( 132 T.success(
137 [][]const u8 { "-ab100" }, 133 [][]const u8{"-ab100"},
138 S{ 134 S{
139 .a = true, 135 .a = true,
140 .b = 100, 136 .b = 100,
141 }, 137 },
142 ), 138 ),
143 T.fail( 139 T.fail(
144 [][]const u8 { "-q" }, 140 [][]const u8{"-q"},
145 error.InvalidArgument, 141 error.InvalidArgument,
146 ), 142 ),
147 T.fail( 143 T.fail(
148 [][]const u8 { "--a" }, 144 [][]const u8{"--a"},
149 error.InvalidArgument, 145 error.InvalidArgument,
150 ), 146 ),
151 T.fail( 147 T.fail(
152 [][]const u8 { "-b=100" }, 148 [][]const u8{"-b=100"},
153 error.ParamNotHandled, 149 error.ParamNotHandled,
154 ), 150 ),
155 T.fail( 151 T.fail(
156 [][]const u8 { "-b=100", "-a" }, 152 [][]const u8{ "-b=100", "-a" },
157 error.InvalidArgument, 153 error.InvalidArgument,
158 ), 154 ),
159 }; 155 };
@@ -182,50 +178,50 @@ test "clap.extended: long" {
182 break :p res; 178 break :p res;
183 }, 179 },
184 Param.option("b", Names.long('b'), &Parser.int(u8, 10)), 180 Param.option("b", Names.long('b'), &Parser.int(u8, 10)),
185 } 181 },
186 }; 182 };
187 183
188 const T = Test(S); 184 const T = Test(S);
189 const tests = []T{ 185 const tests = []T{
190 T.success( 186 T.success(
191 [][]const u8 { "--a" }, 187 [][]const u8{"--a"},
192 S{ 188 S{
193 .a = true, 189 .a = true,
194 .b = 0, 190 .b = 0,
195 }, 191 },
196 ), 192 ),
197 T.success( 193 T.success(
198 [][]const u8 { "--a", "--b", "100" }, 194 [][]const u8{ "--a", "--b", "100" },
199 S{ 195 S{
200 .a = true, 196 .a = true,
201 .b = 100, 197 .b = 100,
202 }, 198 },
203 ), 199 ),
204 T.success( 200 T.success(
205 [][]const u8 { "--a", "--b=100" }, 201 [][]const u8{ "--a", "--b=100" },
206 S{ 202 S{
207 .a = true, 203 .a = true,
208 .b = 100, 204 .b = 100,
209 }, 205 },
210 ), 206 ),
211 T.fail( 207 T.fail(
212 [][]const u8 { "--a=100" }, 208 [][]const u8{"--a=100"},
213 error.DoesntTakeValue, 209 error.DoesntTakeValue,
214 ), 210 ),
215 T.fail( 211 T.fail(
216 [][]const u8 { "--q" }, 212 [][]const u8{"--q"},
217 error.InvalidArgument, 213 error.InvalidArgument,
218 ), 214 ),
219 T.fail( 215 T.fail(
220 [][]const u8 { "-a" }, 216 [][]const u8{"-a"},
221 error.InvalidArgument, 217 error.InvalidArgument,
222 ), 218 ),
223 T.fail( 219 T.fail(
224 [][]const u8 { "--b=100" }, 220 [][]const u8{"--b=100"},
225 error.ParamNotHandled, 221 error.ParamNotHandled,
226 ), 222 ),
227 T.fail( 223 T.fail(
228 [][]const u8 { "--b=100", "--a" }, 224 [][]const u8{ "--b=100", "--a" },
229 error.InvalidArgument, 225 error.InvalidArgument,
230 ), 226 ),
231 }; 227 };
@@ -254,50 +250,50 @@ test "clap.extended: bare" {
254 break :p res; 250 break :p res;
255 }, 251 },
256 Param.option("b", Names.bare('b'), &Parser.int(u8, 10)), 252 Param.option("b", Names.bare('b'), &Parser.int(u8, 10)),
257 } 253 },
258 }; 254 };
259 255
260 const T = Test(S); 256 const T = Test(S);
261 const tests = []T{ 257 const tests = []T{
262 T.success( 258 T.success(
263 [][]const u8 { "a" }, 259 [][]const u8{"a"},
264 S{ 260 S{
265 .a = true, 261 .a = true,
266 .b = 0, 262 .b = 0,
267 }, 263 },
268 ), 264 ),
269 T.success( 265 T.success(
270 [][]const u8 { "a", "b", "100" }, 266 [][]const u8{ "a", "b", "100" },
271 S{ 267 S{
272 .a = true, 268 .a = true,
273 .b = 100, 269 .b = 100,
274 }, 270 },
275 ), 271 ),
276 T.success( 272 T.success(
277 [][]const u8 { "a", "b=100" }, 273 [][]const u8{ "a", "b=100" },
278 S{ 274 S{
279 .a = true, 275 .a = true,
280 .b = 100, 276 .b = 100,
281 }, 277 },
282 ), 278 ),
283 T.fail( 279 T.fail(
284 [][]const u8 { "a=100" }, 280 [][]const u8{"a=100"},
285 error.DoesntTakeValue, 281 error.DoesntTakeValue,
286 ), 282 ),
287 T.fail( 283 T.fail(
288 [][]const u8 { "--a" }, 284 [][]const u8{"--a"},
289 error.InvalidArgument, 285 error.InvalidArgument,
290 ), 286 ),
291 T.fail( 287 T.fail(
292 [][]const u8 { "-a" }, 288 [][]const u8{"-a"},
293 error.InvalidArgument, 289 error.InvalidArgument,
294 ), 290 ),
295 T.fail( 291 T.fail(
296 [][]const u8 { "b=100" }, 292 [][]const u8{"b=100"},
297 error.ParamNotHandled, 293 error.ParamNotHandled,
298 ), 294 ),
299 T.fail( 295 T.fail(
300 [][]const u8 { "b=100", "--a" }, 296 [][]const u8{ "b=100", "--a" },
301 error.InvalidArgument, 297 error.InvalidArgument,
302 ), 298 ),
303 }; 299 };