summaryrefslogtreecommitdiff
path: root/clap/streaming.zig
diff options
context:
space:
mode:
authorGravatar Jimmi Holst Christensen2022-02-25 19:40:00 +0100
committerGravatar Komari Spaghetti2022-03-09 18:12:40 +0100
commit5f7b75d5523d9581eca5a72a362868ff517992e8 (patch)
tree5e874f9c935e0d7c838ea5aadf270ce2929f8e8a /clap/streaming.zig
parentBump actions/checkout from 2.4.0 to 3 (diff)
downloadzig-clap-5f7b75d5523d9581eca5a72a362868ff517992e8.tar.gz
zig-clap-5f7b75d5523d9581eca5a72a362868ff517992e8.tar.xz
zig-clap-5f7b75d5523d9581eca5a72a362868ff517992e8.zip
Allow for clap to parse argument values into types
This changes - `.flag`, `.option`, `.options` and `.positionals` are now just fields you access on the result of `parse` and `parseEx`. - `clap.ComptimeClap` has been removed. - `clap.StreamingClap` is now called `clap.streaming.Clap` - `parse` and `parseEx` now takes a `value_parsers` argument that provides the parsers to parse values. - Remove `helpEx`, `helpFull`, `usageEx` and `usageFull`. They now just expect `Id` to have methods for getting the description and value texts.
Diffstat (limited to 'clap/streaming.zig')
-rw-r--r--clap/streaming.zig34
1 files changed, 21 insertions, 13 deletions
diff --git a/clap/streaming.zig b/clap/streaming.zig
index 8eca51a..2ab9c8d 100644
--- a/clap/streaming.zig
+++ b/clap/streaming.zig
@@ -10,7 +10,7 @@ const mem = std.mem;
10const os = std.os; 10const os = std.os;
11const testing = std.testing; 11const testing = std.testing;
12 12
13/// The result returned from StreamingClap.next 13/// The result returned from Clap.next
14pub fn Arg(comptime Id: type) type { 14pub fn Arg(comptime Id: type) type {
15 return struct { 15 return struct {
16 const Self = @This(); 16 const Self = @This();
@@ -20,10 +20,18 @@ pub fn Arg(comptime Id: type) type {
20 }; 20 };
21} 21}
22 22
23pub const Error = error{
24 MissingValue,
25 InvalidArgument,
26 DoesntTakeValue,
27};
28
23/// A command line argument parser which, given an ArgIterator, will parse arguments according 29/// A command line argument parser which, given an ArgIterator, will parse arguments according
24/// to the params. StreamingClap parses in an iterating manner, so you have to use a loop 30/// to the params. Clap parses in an iterating manner, so you have to use a loop together with
25/// together with StreamingClap.next to parse all the arguments of your program. 31/// Clap.next to parse all the arguments of your program.
26pub fn StreamingClap(comptime Id: type, comptime ArgIterator: type) type { 32///
33/// This parser is the building block for all the more complicated parsers.
34pub fn Clap(comptime Id: type, comptime ArgIterator: type) type {
27 return struct { 35 return struct {
28 const State = union(enum) { 36 const State = union(enum) {
29 normal, 37 normal,
@@ -71,7 +79,7 @@ pub fn StreamingClap(comptime Id: type, comptime ArgIterator: type) type {
71 continue; 79 continue;
72 if (param.takes_value == .none) { 80 if (param.takes_value == .none) {
73 if (maybe_value != null) 81 if (maybe_value != null)
74 return parser.err(arg, .{ .long = name }, error.DoesntTakeValue); 82 return parser.err(arg, .{ .long = name }, Error.DoesntTakeValue);
75 83
76 return Arg(Id){ .param = param }; 84 return Arg(Id){ .param = param };
77 } 85 }
@@ -81,13 +89,13 @@ pub fn StreamingClap(comptime Id: type, comptime ArgIterator: type) type {
81 break :blk v; 89 break :blk v;
82 90
83 break :blk parser.iter.next() orelse 91 break :blk parser.iter.next() orelse
84 return parser.err(arg, .{ .long = name }, error.MissingValue); 92 return parser.err(arg, .{ .long = name }, Error.MissingValue);
85 }; 93 };
86 94
87 return Arg(Id){ .param = param, .value = value }; 95 return Arg(Id){ .param = param, .value = value };
88 } 96 }
89 97
90 return parser.err(arg, .{ .long = name }, error.InvalidArgument); 98 return parser.err(arg, .{ .long = name }, Error.InvalidArgument);
91 }, 99 },
92 .short => return try parser.chaining(.{ 100 .short => return try parser.chaining(.{
93 .arg = arg, 101 .arg = arg,
@@ -105,7 +113,7 @@ pub fn StreamingClap(comptime Id: type, comptime ArgIterator: type) type {
105 113
106 return Arg(Id){ .param = param, .value = arg }; 114 return Arg(Id){ .param = param, .value = arg };
107 } else { 115 } else {
108 return parser.err(arg, .{}, error.InvalidArgument); 116 return parser.err(arg, .{}, Error.InvalidArgument);
109 }, 117 },
110 } 118 }
111 } 119 }
@@ -137,13 +145,13 @@ pub fn StreamingClap(comptime Id: type, comptime ArgIterator: type) type {
137 const next_is_eql = if (next_index < arg.len) arg[next_index] == '=' else false; 145 const next_is_eql = if (next_index < arg.len) arg[next_index] == '=' else false;
138 if (param.takes_value == .none) { 146 if (param.takes_value == .none) {
139 if (next_is_eql) 147 if (next_is_eql)
140 return parser.err(arg, .{ .short = short }, error.DoesntTakeValue); 148 return parser.err(arg, .{ .short = short }, Error.DoesntTakeValue);
141 return Arg(Id){ .param = param }; 149 return Arg(Id){ .param = param };
142 } 150 }
143 151
144 if (arg.len <= next_index) { 152 if (arg.len <= next_index) {
145 const value = parser.iter.next() orelse 153 const value = parser.iter.next() orelse
146 return parser.err(arg, .{ .short = short }, error.MissingValue); 154 return parser.err(arg, .{ .short = short }, Error.MissingValue);
147 155
148 return Arg(Id){ .param = param, .value = value }; 156 return Arg(Id){ .param = param, .value = value };
149 } 157 }
@@ -154,7 +162,7 @@ pub fn StreamingClap(comptime Id: type, comptime ArgIterator: type) type {
154 return Arg(Id){ .param = param, .value = arg[next_index..] }; 162 return Arg(Id){ .param = param, .value = arg[next_index..] };
155 } 163 }
156 164
157 return parser.err(arg, .{ .short = arg[index] }, error.InvalidArgument); 165 return parser.err(arg, .{ .short = arg[index] }, Error.InvalidArgument);
158 } 166 }
159 167
160 fn positionalParam(parser: *@This()) ?*const clap.Param(Id) { 168 fn positionalParam(parser: *@This()) ?*const clap.Param(Id) {
@@ -209,7 +217,7 @@ fn testNoErr(
209 results: []const Arg(u8), 217 results: []const Arg(u8),
210) !void { 218) !void {
211 var iter = args.SliceIterator{ .args = args_strings }; 219 var iter = args.SliceIterator{ .args = args_strings };
212 var c = StreamingClap(u8, args.SliceIterator){ 220 var c = Clap(u8, args.SliceIterator){
213 .params = params, 221 .params = params,
214 .iter = &iter, 222 .iter = &iter,
215 }; 223 };
@@ -236,7 +244,7 @@ fn testErr(
236) !void { 244) !void {
237 var diag: clap.Diagnostic = undefined; 245 var diag: clap.Diagnostic = undefined;
238 var iter = args.SliceIterator{ .args = args_strings }; 246 var iter = args.SliceIterator{ .args = args_strings };
239 var c = StreamingClap(u8, args.SliceIterator){ 247 var c = Clap(u8, args.SliceIterator){
240 .params = params, 248 .params = params,
241 .iter = &iter, 249 .iter = &iter,
242 .diagnostic = &diag, 250 .diagnostic = &diag,