summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar Jimmi HC2019-06-12 15:30:30 +0200
committerGravatar Jimmi HC2019-06-12 15:30:30 +0200
commit44ea38f25453fbf51de72505d7b3ddb0f3eec13c (patch)
tree2ffd0fc94f65270f9f94edab940641b388ff3f16 /src
parenttried to fix travis (diff)
downloadzig-clap-44ea38f25453fbf51de72505d7b3ddb0f3eec13c.tar.gz
zig-clap-44ea38f25453fbf51de72505d7b3ddb0f3eec13c.tar.xz
zig-clap-44ea38f25453fbf51de72505d7b3ddb0f3eec13c.zip
updated to newest version of zig
Diffstat (limited to 'src')
-rw-r--r--src/args.zig13
-rw-r--r--src/comptime.zig68
-rw-r--r--src/index.zig276
-rw-r--r--src/streaming.zig217
4 files changed, 166 insertions, 408 deletions
diff --git a/src/args.zig b/src/args.zig
index a34c14c..4234ada 100644
--- a/src/args.zig
+++ b/src/args.zig
@@ -21,14 +21,7 @@ pub const SliceIterator = struct {
21 const Error = error{}; 21 const Error = error{};
22 22
23 args: []const []const u8, 23 args: []const []const u8,
24 index: usize, 24 index: usize = 0,
25
26 pub fn init(args: []const []const u8) SliceIterator {
27 return SliceIterator{
28 .args = args,
29 .index = 0,
30 };
31 }
32 25
33 pub fn next(iter: *SliceIterator) Error!?[]const u8 { 26 pub fn next(iter: *SliceIterator) Error!?[]const u8 {
34 if (iter.args.len <= iter.index) 27 if (iter.args.len <= iter.index)
@@ -40,8 +33,8 @@ pub const SliceIterator = struct {
40}; 33};
41 34
42test "clap.args.SliceIterator" { 35test "clap.args.SliceIterator" {
43 const args = [][]const u8{ "A", "BB", "CCC" }; 36 const args = [_][]const u8{ "A", "BB", "CCC" };
44 var iter = SliceIterator.init(args); 37 var iter = SliceIterator{ .args = args };
45 38
46 for (args) |a| { 39 for (args) |a| {
47 const b = try iter.next(); 40 const b = try iter.next();
diff --git a/src/comptime.zig b/src/comptime.zig
index b9021de..b585598 100644
--- a/src/comptime.zig
+++ b/src/comptime.zig
@@ -1,4 +1,4 @@
1const clap = @import("index.zig"); 1const clap = @import("../clap.zig");
2const std = @import("std"); 2const std = @import("std");
3 3
4const testing = std.testing; 4const testing = std.testing;
@@ -8,7 +8,7 @@ const mem = std.mem;
8pub fn ComptimeClap(comptime Id: type, comptime params: []const clap.Param(Id)) type { 8pub fn ComptimeClap(comptime Id: type, comptime params: []const clap.Param(Id)) type {
9 var flags: usize = 0; 9 var flags: usize = 0;
10 var options: usize = 0; 10 var options: usize = 0;
11 var converted_params: []const clap.Param(usize) = []clap.Param(usize){}; 11 var converted_params: []const clap.Param(usize) = [_]clap.Param(usize){};
12 for (params) |param| { 12 for (params) |param| {
13 const index = blk: { 13 const index = blk: {
14 if (param.names.long == null and param.names.short == null) 14 if (param.names.long == null and param.names.short == null)
@@ -24,8 +24,12 @@ pub fn ComptimeClap(comptime Id: type, comptime params: []const clap.Param(Id))
24 break :blk res; 24 break :blk res;
25 }; 25 };
26 26
27 const converted = clap.Param(usize).init(index, param.takes_value, param.names); 27 const converted = clap.Param(usize){
28 converted_params = converted_params ++ []clap.Param(usize){converted}; 28 .id = index,
29 .names = param.names,
30 .takes_value = param.takes_value,
31 };
32 converted_params = converted_params ++ [_]clap.Param(usize){converted};
29 } 33 }
30 34
31 return struct { 35 return struct {
@@ -37,13 +41,16 @@ pub fn ComptimeClap(comptime Id: type, comptime params: []const clap.Param(Id))
37 pub fn parse(allocator: *mem.Allocator, comptime ArgIter: type, iter: *ArgIter) !@This() { 41 pub fn parse(allocator: *mem.Allocator, comptime ArgIter: type, iter: *ArgIter) !@This() {
38 var pos = std.ArrayList([]const u8).init(allocator); 42 var pos = std.ArrayList([]const u8).init(allocator);
39 var res = @This(){ 43 var res = @This(){
40 .options = []?[]const u8{null} ** options, 44 .options = [_]?[]const u8{null} ** options,
41 .flags = []bool{false} ** flags, 45 .flags = [_]bool{false} ** flags,
42 .pos = undefined, 46 .pos = undefined,
43 .allocator = allocator, 47 .allocator = allocator,
44 }; 48 };
45 49
46 var stream = clap.StreamingClap(usize, ArgIter).init(converted_params, iter); 50 var stream = clap.StreamingClap(usize, ArgIter){
51 .params = converted_params,
52 .iter = iter,
53 };
47 while (try stream.next()) |arg| { 54 while (try stream.next()) |arg| {
48 const param = arg.param; 55 const param = arg.param;
49 if (param.names.long == null and param.names.short == null) { 56 if (param.names.long == null and param.names.short == null) {
@@ -90,7 +97,7 @@ pub fn ComptimeClap(comptime Id: type, comptime params: []const clap.Param(Id))
90 comptime { 97 comptime {
91 for (converted_params) |param| { 98 for (converted_params) |param| {
92 if (param.names.short) |s| { 99 if (param.names.short) |s| {
93 if (mem.eql(u8, name, "-" ++ []u8{s})) 100 if (mem.eql(u8, name, "-" ++ [_]u8{s}))
94 return param; 101 return param;
95 } 102 }
96 if (param.names.long) |l| { 103 if (param.names.long) |l| {
@@ -106,27 +113,38 @@ pub fn ComptimeClap(comptime Id: type, comptime params: []const clap.Param(Id))
106} 113}
107 114
108test "clap.comptime.ComptimeClap" { 115test "clap.comptime.ComptimeClap" {
109 const Clap = ComptimeClap(void, comptime []clap.Param(void){ 116 const Clap = ComptimeClap(void, [_]clap.Param(void){
110 clap.Param(void).flag({}, clap.Names{ 117 clap.Param(void){
111 .short = 'a', 118 .names = clap.Names{
112 .long = "aa", 119 .short = 'a',
113 }), 120 .long = "aa",
114 clap.Param(void).flag({}, clap.Names{ 121 }
115 .short = 'b', 122 },
116 .long = "bb", 123 clap.Param(void){
117 }), 124 .names = clap.Names{
118 clap.Param(void).option({}, clap.Names{ 125 .short = 'b',
119 .short = 'c', 126 .long = "bb",
120 .long = "cc", 127 }
121 }), 128 },
122 clap.Param(void).positional({}), 129 clap.Param(void){
130 .names = clap.Names{
131 .short = 'c',
132 .long = "cc",
133 },
134 .takes_value = true,
135 },
136 clap.Param(void){
137 .takes_value = true,
138 },
123 }); 139 });
124 140
125 var buf: [1024]u8 = undefined; 141 var buf: [1024]u8 = undefined;
126 var fb_allocator = heap.FixedBufferAllocator.init(buf[0..]); 142 var fb_allocator = heap.FixedBufferAllocator.init(buf[0..]);
127 var iter = clap.args.SliceIterator.init([][]const u8{ 143 var iter = clap.args.SliceIterator{
128 "-a", "-c", "0", "something", 144 .args = [_][]const u8{
129 }); 145 "-a", "-c", "0", "something",
146 },
147 };
130 var args = try Clap.parse(&fb_allocator.allocator, clap.args.SliceIterator, &iter); 148 var args = try Clap.parse(&fb_allocator.allocator, clap.args.SliceIterator, &iter);
131 defer args.deinit(); 149 defer args.deinit();
132 150
diff --git a/src/index.zig b/src/index.zig
deleted file mode 100644
index 40ad849..0000000
--- a/src/index.zig
+++ /dev/null
@@ -1,276 +0,0 @@
1const std = @import("std");
2
3const debug = std.debug;
4const io = std.io;
5const mem = std.mem;
6
7pub const @"comptime" = @import("comptime.zig");
8pub const args = @import("args.zig");
9pub const streaming = @import("streaming.zig");
10
11test "clap" {
12 _ = @"comptime";
13 _ = args;
14 _ = streaming;
15}
16
17pub const ComptimeClap = @"comptime".ComptimeClap;
18pub const StreamingClap = streaming.StreamingClap;
19
20/// The names a ::Param can have.
21pub const Names = struct {
22 /// '-' prefix
23 short: ?u8,
24
25 /// '--' prefix
26 long: ?[]const u8,
27
28 /// Initializes a short name
29 pub fn short(s: u8) Names {
30 return Names{
31 .short = s,
32 .long = null,
33 };
34 }
35
36 /// Initializes a long name
37 pub fn long(l: []const u8) Names {
38 return Names{
39 .short = null,
40 .long = l,
41 };
42 }
43
44 /// Initializes a name that is long and short, from the same string.
45 /// ::short is set to ::name[0], and ::long is set to ::name.
46 /// This function asserts that ::name.len != 0
47 pub fn both(name: []const u8) Names {
48 debug.assert(name.len != 0);
49
50 return Names{
51 .short = name[0],
52 .long = name,
53 };
54 }
55};
56
57/// Represents a parameter for the command line.
58/// Parameters come in three kinds:
59/// * Short ("-a"): Should be used for the most commonly used parameters in your program.
60/// * They can take a value three different ways.
61/// * "-a value"
62/// * "-a=value"
63/// * "-avalue"
64/// * They chain if they don't take values: "-abc".
65/// * The last given parameter can take a value in the same way that a single parameter can:
66/// * "-abc value"
67/// * "-abc=value"
68/// * "-abcvalue"
69/// * Long ("--long-param"): Should be used for less common parameters, or when no single character
70/// can describe the paramter.
71/// * They can take a value two different ways.
72/// * "--long-param value"
73/// * "--long-param=value"
74/// * Positional: Should be used as the primary parameter of the program, like a filename or
75/// an expression to parse.
76/// * Positional parameters have both names.long and names.short == null.
77/// * Positional parameters must take a value.
78pub fn Param(comptime Id: type) type {
79 return struct {
80 id: Id,
81 takes_value: bool,
82 names: Names,
83
84 pub fn flag(id: Id, names: Names) @This() {
85 return init(id, false, names);
86 }
87
88 pub fn option(id: Id, names: Names) @This() {
89 return init(id, true, names);
90 }
91
92 pub fn positional(id: Id) @This() {
93 return init(id, true, Names{ .short = null, .long = null });
94 }
95
96 pub fn init(id: Id, takes_value: bool, names: Names) @This() {
97 // Assert, that if the param have no name, then it has to take
98 // a value.
99 debug.assert(names.long != null or
100 names.short != null or
101 takes_value);
102
103 return @This(){
104 .id = id,
105 .takes_value = takes_value,
106 .names = names,
107 };
108 }
109 };
110}
111
112/// Will print a help message in the following format:
113/// -s, --long=value_text help_text
114/// -s, help_text
115/// --long help_text
116pub fn helpFull(
117 stream: var,
118 comptime Id: type,
119 params: []const Param(Id),
120 comptime Error: type,
121 context: var,
122 help_text: fn (@typeOf(context), Param(Id)) Error![]const u8,
123 value_text: fn (@typeOf(context), Param(Id)) Error![]const u8,
124) !void {
125 const max_spacing = blk: {
126 var res: usize = 0;
127 for (params) |param| {
128 var counting_stream = io.CountingOutStream(io.NullOutStream.Error).init(io.null_out_stream);
129 try printParam(&counting_stream.stream, Id, param, Error, context, value_text);
130 if (res < counting_stream.bytes_written)
131 res = counting_stream.bytes_written;
132 }
133
134 break :blk res;
135 };
136
137 for (params) |param| {
138 if (param.names.short == null and param.names.long == null)
139 continue;
140
141 var counting_stream = io.CountingOutStream(@typeOf(stream.*).Error).init(stream);
142 try stream.print("\t");
143 try printParam(&counting_stream.stream, Id, param, Error, context, value_text);
144 try stream.writeByteNTimes(' ', max_spacing - counting_stream.bytes_written);
145 try stream.print("\t{}\n", try help_text(context, param));
146 }
147}
148
149fn printParam(
150 stream: var,
151 comptime Id: type,
152 param: Param(Id),
153 comptime Error: type,
154 context: var,
155 value_text: fn (@typeOf(context), Param(Id)) Error![]const u8,
156) @typeOf(stream.*).Error!void {
157 if (param.names.short) |s| {
158 try stream.print("-{c}", s);
159 } else {
160 try stream.print(" ");
161 }
162 if (param.names.long) |l| {
163 if (param.names.short) |_| {
164 try stream.print(", ");
165 } else {
166 try stream.print(" ");
167 }
168
169 try stream.print("--{}", l);
170 }
171 if (param.takes_value)
172 try stream.print("={}", value_text(context, param));
173}
174
175/// A wrapper around helpFull for simple help_text and value_text functions that
176/// cant return an error or take a context.
177pub fn helpEx(
178 stream: var,
179 comptime Id: type,
180 params: []const Param(Id),
181 help_text: fn (Param(Id)) []const u8,
182 value_text: fn (Param(Id)) []const u8,
183) !void {
184 const Context = struct {
185 help_text: fn (Param(Id)) []const u8,
186 value_text: fn (Param(Id)) []const u8,
187
188 pub fn help(c: @This(), p: Param(Id)) error{}![]const u8 {
189 return c.help_text(p);
190 }
191
192 pub fn value(c: @This(), p: Param(Id)) error{}![]const u8 {
193 return c.value_text(p);
194 }
195 };
196
197 return helpFull(
198 stream,
199 Id,
200 params,
201 error{},
202 Context{
203 .help_text = help_text,
204 .value_text = value_text,
205 },
206 Context.help,
207 Context.value,
208 );
209}
210
211/// A wrapper around helpEx that takes a Param([]const u8) and uses the string id
212/// as the help text for each paramter.
213pub fn help(stream: var, params: []const Param([]const u8)) !void {
214 try helpEx(stream, []const u8, params, getHelpSimple, getValueSimple);
215}
216
217fn getHelpSimple(param: Param([]const u8)) []const u8 {
218 return param.id;
219}
220
221fn getValueSimple(param: Param([]const u8)) []const u8 {
222 return "VALUE";
223}
224
225test "clap.help" {
226 var buf: [1024]u8 = undefined;
227 var slice_stream = io.SliceOutStream.init(buf[0..]);
228 try help(
229 &slice_stream.stream,
230 []Param([]const u8){
231 Param([]const u8).flag(
232 "Short flag.",
233 Names.short('a'),
234 ),
235 Param([]const u8).option(
236 "Short option.",
237 Names.short('b'),
238 ),
239 Param([]const u8).flag(
240 "Long flag.",
241 Names.long("aa"),
242 ),
243 Param([]const u8).option(
244 "Long option.",
245 Names.long("bb"),
246 ),
247 Param([]const u8).flag(
248 "Both flag.",
249 Names.both("cc"),
250 ),
251 Param([]const u8).option(
252 "Both option.",
253 Names.both("dd"),
254 ),
255 Param([]const u8).positional(
256 "Positional. This should not appear in the help message.",
257 ),
258 },
259 );
260
261 const expected = "" ++
262 "\t-a \tShort flag.\n" ++
263 "\t-b=VALUE \tShort option.\n" ++
264 "\t --aa \tLong flag.\n" ++
265 "\t --bb=VALUE\tLong option.\n" ++
266 "\t-c, --cc \tBoth flag.\n" ++
267 "\t-d, --dd=VALUE\tBoth option.\n";
268
269 if (!mem.eql(u8, slice_stream.getWritten(), expected)) {
270 debug.warn("============ Expected ============\n");
271 debug.warn("{}", expected);
272 debug.warn("============= Actual =============\n");
273 debug.warn("{}", slice_stream.getWritten());
274 return error.NoMatch;
275 }
276}
diff --git a/src/streaming.zig b/src/streaming.zig
index 7bdc71f..9da120c 100644
--- a/src/streaming.zig
+++ b/src/streaming.zig
@@ -1,5 +1,5 @@
1const builtin = @import("builtin"); 1const builtin = @import("builtin");
2const clap = @import("index.zig"); 2const clap = @import("../clap.zig");
3const std = @import("std"); 3const std = @import("std");
4 4
5const args = clap.args; 5const args = clap.args;
@@ -14,14 +14,7 @@ pub fn Arg(comptime Id: type) type {
14 const Self = @This(); 14 const Self = @This();
15 15
16 param: *const clap.Param(Id), 16 param: *const clap.Param(Id),
17 value: ?[]const u8, 17 value: ?[]const u8 = null,
18
19 pub fn init(param: *const clap.Param(Id), value: ?[]const u8) Self {
20 return Self{
21 .param = param,
22 .value = value,
23 };
24 }
25 }; 18 };
26} 19}
27 20
@@ -42,17 +35,7 @@ pub fn StreamingClap(comptime Id: type, comptime ArgIterator: type) type {
42 35
43 params: []const clap.Param(Id), 36 params: []const clap.Param(Id),
44 iter: *ArgIterator, 37 iter: *ArgIterator,
45 state: State, 38 state: State = State.Normal,
46
47 pub fn init(params: []const clap.Param(Id), iter: *ArgIterator) @This() {
48 var res = @This(){
49 .params = params,
50 .iter = iter,
51 .state = State.Normal,
52 };
53
54 return res;
55 }
56 39
57 /// Get the next ::Arg that matches a ::Param. 40 /// Get the next ::Arg that matches a ::Param.
58 pub fn next(parser: *@This()) !?Arg(Id) { 41 pub fn next(parser: *@This()) !?Arg(Id) {
@@ -107,7 +90,7 @@ pub fn StreamingClap(comptime Id: type, comptime ArgIterator: type) type {
107 if (maybe_value != null) 90 if (maybe_value != null)
108 return error.DoesntTakeValue; 91 return error.DoesntTakeValue;
109 92
110 return Arg(Id).init(param, null); 93 return Arg(Id){ .param = param };
111 } 94 }
112 95
113 const value = blk: { 96 const value = blk: {
@@ -117,7 +100,7 @@ pub fn StreamingClap(comptime Id: type, comptime ArgIterator: type) type {
117 break :blk (try parser.iter.next()) orelse return error.MissingValue; 100 break :blk (try parser.iter.next()) orelse return error.MissingValue;
118 }; 101 };
119 102
120 return Arg(Id).init(param, value); 103 return Arg(Id){ .param = param, .value = value };
121 } 104 }
122 }, 105 },
123 ArgInfo.Kind.Short => { 106 ArgInfo.Kind.Short => {
@@ -133,7 +116,7 @@ pub fn StreamingClap(comptime Id: type, comptime ArgIterator: type) type {
133 if (param.names.short) |_| 116 if (param.names.short) |_|
134 continue; 117 continue;
135 118
136 return Arg(Id).init(param, arg); 119 return Arg(Id){ .param = param, .value = arg };
137 } 120 }
138 }, 121 },
139 } 122 }
@@ -169,18 +152,17 @@ pub fn StreamingClap(comptime Id: type, comptime ArgIterator: type) type {
169 } 152 }
170 153
171 if (!param.takes_value) 154 if (!param.takes_value)
172 return Arg(Id).init(param, null); 155 return Arg(Id){ .param = param };
173 156
174 if (arg.len <= next_index) { 157 if (arg.len <= next_index) {
175 const value = (try parser.iter.next()) orelse return error.MissingValue; 158 const value = (try parser.iter.next()) orelse return error.MissingValue;
176 return Arg(Id).init(param, value); 159 return Arg(Id){ .param = param, .value = value };
177 } 160 }
178 161
179 if (arg[next_index] == '=') { 162 if (arg[next_index] == '=')
180 return Arg(Id).init(param, arg[next_index + 1 ..]); 163 return Arg(Id){ .param = param, .value = arg[next_index + 1 ..] };
181 }
182 164
183 return Arg(Id).init(param, arg[next_index..]); 165 return Arg(Id){ .param = param, .value = arg[next_index..] };
184 } 166 }
185 167
186 return error.InvalidArgument; 168 return error.InvalidArgument;
@@ -189,8 +171,11 @@ pub fn StreamingClap(comptime Id: type, comptime ArgIterator: type) type {
189} 171}
190 172
191fn testNoErr(params: []const clap.Param(u8), args_strings: []const []const u8, results: []const Arg(u8)) void { 173fn testNoErr(params: []const clap.Param(u8), args_strings: []const []const u8, results: []const Arg(u8)) void {
192 var iter = args.SliceIterator.init(args_strings); 174 var iter = args.SliceIterator{ .args = args_strings };
193 var c = StreamingClap(u8, args.SliceIterator).init(params, &iter); 175 var c = StreamingClap(u8, args.SliceIterator){
176 .params = params,
177 .iter = &iter
178 };
194 179
195 for (results) |res| { 180 for (results) |res| {
196 const arg = (c.next() catch unreachable) orelse unreachable; 181 const arg = (c.next() catch unreachable) orelse unreachable;
@@ -209,10 +194,20 @@ fn testNoErr(params: []const clap.Param(u8), args_strings: []const []const u8, r
209} 194}
210 195
211test "clap.streaming.StreamingClap: short params" { 196test "clap.streaming.StreamingClap: short params" {
212 const params = []clap.Param(u8){ 197 const params = [_]clap.Param(u8){
213 clap.Param(u8).flag(0, clap.Names.short('a')), 198 clap.Param(u8){
214 clap.Param(u8).flag(1, clap.Names.short('b')), 199 .id = 0,
215 clap.Param(u8).option(2, clap.Names.short('c')), 200 .names = clap.Names{ .short = 'a' },
201 },
202 clap.Param(u8){
203 .id = 1,
204 .names = clap.Names{ .short = 'b' },
205 },
206 clap.Param(u8){
207 .id = 2,
208 .names = clap.Names{ .short = 'c' },
209 .takes_value = true,
210 },
216 }; 211 };
217 212
218 const a = &params[0]; 213 const a = &params[0];
@@ -221,33 +216,43 @@ test "clap.streaming.StreamingClap: short params" {
221 216
222 testNoErr( 217 testNoErr(
223 params, 218 params,
224 [][]const u8{ 219 [_][]const u8{
225 "-a", "-b", "-ab", "-ba", 220 "-a", "-b", "-ab", "-ba",
226 "-c", "0", "-c=0", "-ac", 221 "-c", "0", "-c=0", "-ac",
227 "0", "-ac=0", 222 "0", "-ac=0",
228 }, 223 },
229 []const Arg(u8){ 224 [_]Arg(u8){
230 Arg(u8).init(a, null), 225 Arg(u8){ .param = a },
231 Arg(u8).init(b, null), 226 Arg(u8){ .param = b },
232 Arg(u8).init(a, null), 227 Arg(u8){ .param = a },
233 Arg(u8).init(b, null), 228 Arg(u8){ .param = b },
234 Arg(u8).init(b, null), 229 Arg(u8){ .param = b },
235 Arg(u8).init(a, null), 230 Arg(u8){ .param = a },
236 Arg(u8).init(c, "0"), 231 Arg(u8){ .param = c, .value = "0" },
237 Arg(u8).init(c, "0"), 232 Arg(u8){ .param = c, .value = "0" },
238 Arg(u8).init(a, null), 233 Arg(u8){ .param = a },
239 Arg(u8).init(c, "0"), 234 Arg(u8){ .param = c, .value = "0" },
240 Arg(u8).init(a, null), 235 Arg(u8){ .param = a },
241 Arg(u8).init(c, "0"), 236 Arg(u8){ .param = c, .value = "0" },
242 }, 237 },
243 ); 238 );
244} 239}
245 240
246test "clap.streaming.StreamingClap: long params" { 241test "clap.streaming.StreamingClap: long params" {
247 const params = []clap.Param(u8){ 242 const params = [_]clap.Param(u8){
248 clap.Param(u8).flag(0, clap.Names.long("aa")), 243 clap.Param(u8){
249 clap.Param(u8).flag(1, clap.Names.long("bb")), 244 .id = 0,
250 clap.Param(u8).option(2, clap.Names.long("cc")), 245 .names = clap.Names{ .long = "aa" },
246 },
247 clap.Param(u8){
248 .id = 1,
249 .names = clap.Names{ .long = "bb" },
250 },
251 clap.Param(u8){
252 .id = 2,
253 .names = clap.Names{ .long = "cc" },
254 .takes_value = true,
255 },
251 }; 256 };
252 257
253 const aa = &params[0]; 258 const aa = &params[0];
@@ -256,48 +261,66 @@ test "clap.streaming.StreamingClap: long params" {
256 261
257 testNoErr( 262 testNoErr(
258 params, 263 params,
259 [][]const u8{ 264 [_][]const u8{
260 "--aa", "--bb", 265 "--aa", "--bb",
261 "--cc", "0", 266 "--cc", "0",
262 "--cc=0", 267 "--cc=0",
263 }, 268 },
264 []const Arg(u8){ 269 [_]Arg(u8){
265 Arg(u8).init(aa, null), 270 Arg(u8){ .param = aa },
266 Arg(u8).init(bb, null), 271 Arg(u8){ .param = bb },
267 Arg(u8).init(cc, "0"), 272 Arg(u8){ .param = cc, .value = "0" },
268 Arg(u8).init(cc, "0"), 273 Arg(u8){ .param = cc, .value = "0" },
269 }, 274 },
270 ); 275 );
271} 276}
272 277
273test "clap.streaming.StreamingClap: positional params" { 278test "clap.streaming.StreamingClap: positional params" {
274 const params = []clap.Param(u8){clap.Param(u8).positional(0)}; 279 const params = [_]clap.Param(u8){
280 clap.Param(u8){
281 .id = 0,
282 .takes_value = true,
283 },
284 };
275 285
276 testNoErr( 286 testNoErr(
277 params, 287 params,
278 [][]const u8{ "aa", "bb" }, 288 [_][]const u8{ "aa", "bb" },
279 []const Arg(u8){ 289 [_]Arg(u8){
280 Arg(u8).init(&params[0], "aa"), 290 Arg(u8){ .param = &params[0], .value = "aa" },
281 Arg(u8).init(&params[0], "bb"), 291 Arg(u8){ .param = &params[0], .value = "bb" },
282 }, 292 },
283 ); 293 );
284} 294}
285 295
286test "clap.streaming.StreamingClap: all params" { 296test "clap.streaming.StreamingClap: all params" {
287 const params = []clap.Param(u8){ 297 const params = [_]clap.Param(u8){
288 clap.Param(u8).flag(0, clap.Names{ 298 clap.Param(u8){
289 .short = 'a', 299 .id = 0,
290 .long = "aa", 300 .names = clap.Names{
291 }), 301 .short = 'a',
292 clap.Param(u8).flag(1, clap.Names{ 302 .long = "aa",
293 .short = 'b', 303 },
294 .long = "bb", 304 },
295 }), 305 clap.Param(u8){
296 clap.Param(u8).option(2, clap.Names{ 306 .id = 1,
297 .short = 'c', 307 .names = clap.Names{
298 .long = "cc", 308 .short = 'b',
299 }), 309 .long = "bb",
300 clap.Param(u8).positional(3), 310 },
311 },
312 clap.Param(u8){
313 .id = 2,
314 .names = clap.Names{
315 .short = 'c',
316 .long = "cc",
317 },
318 .takes_value = true,
319 },
320 clap.Param(u8){
321 .id = 3,
322 .takes_value = true,
323 },
301 }; 324 };
302 325
303 const aa = &params[0]; 326 const aa = &params[0];
@@ -307,30 +330,30 @@ test "clap.streaming.StreamingClap: all params" {
307 330
308 testNoErr( 331 testNoErr(
309 params, 332 params,
310 [][]const u8{ 333 [_][]const u8{
311 "-a", "-b", "-ab", "-ba", 334 "-a", "-b", "-ab", "-ba",
312 "-c", "0", "-c=0", "-ac", 335 "-c", "0", "-c=0", "-ac",
313 "0", "-ac=0", "--aa", "--bb", 336 "0", "-ac=0", "--aa", "--bb",
314 "--cc", "0", "--cc=0", "something", 337 "--cc", "0", "--cc=0", "something",
315 }, 338 },
316 []const Arg(u8){ 339 [_]Arg(u8){
317 Arg(u8).init(aa, null), 340 Arg(u8){ .param = aa },
318 Arg(u8).init(bb, null), 341 Arg(u8){ .param = bb },
319 Arg(u8).init(aa, null), 342 Arg(u8){ .param = aa },
320 Arg(u8).init(bb, null), 343 Arg(u8){ .param = bb },
321 Arg(u8).init(bb, null), 344 Arg(u8){ .param = bb },
322 Arg(u8).init(aa, null), 345 Arg(u8){ .param = aa },
323 Arg(u8).init(cc, "0"), 346 Arg(u8){ .param = cc, .value = "0" },
324 Arg(u8).init(cc, "0"), 347 Arg(u8){ .param = cc, .value = "0" },
325 Arg(u8).init(aa, null), 348 Arg(u8){ .param = aa },
326 Arg(u8).init(cc, "0"), 349 Arg(u8){ .param = cc, .value = "0" },
327 Arg(u8).init(aa, null), 350 Arg(u8){ .param = aa },
328 Arg(u8).init(cc, "0"), 351 Arg(u8){ .param = cc, .value = "0" },
329 Arg(u8).init(aa, null), 352 Arg(u8){ .param = aa },
330 Arg(u8).init(bb, null), 353 Arg(u8){ .param = bb },
331 Arg(u8).init(cc, "0"), 354 Arg(u8){ .param = cc, .value = "0" },
332 Arg(u8).init(cc, "0"), 355 Arg(u8){ .param = cc, .value = "0" },
333 Arg(u8).init(positional, "something"), 356 Arg(u8){ .param = positional, .value = "something" },
334 }, 357 },
335 ); 358 );
336} 359}